Learn by reading through in order

datetime and time — Working with Dates, Times, and Elapsed Time

Learn Python's datetime / time / calendar modules from the ground up. Covers date arithmetic with date / datetime / timedelta, string conversion via strftime / strptime, and elapsed-time measurement with time.perf_counter — all hands-on.

This article walks through the three standard libraries that handle dates, times, and elapsed timedatetime / time / calendar. You'll see date arithmetic with date / datetime / timedelta, two-way string conversion with strftime / strptime, and elapsed-time measurement with time.perf_counter.

date / datetime / timedelta — Creating Dates and Computing Differences

When you work with dates in Python, you pick from three classes in the datetime module. date holds year/month/day only, datetime adds hour/minute/second, and timedelta represents a duration like "3 days" or "2 hours". The design is symmetric: date + timedelta gives you "3 days from now", and date - date returns the gap between two dates as a timedelta.

How date / datetime / timedelta Relate
dateyear / month / daydatetimeyear / month / day + timetimedeltaduration (gap / offset)
date and datetime represent points in time; timedelta represents the gap between them or an amount to add.
ClassWhat it storesTypical use
dateyear / month / dayBirthdays, order dates — anything where only the date matters
datetimeyear / month / day + hour / minute / secondLogs, file modification times — anything where the time matters too
timedeltadays / seconds / microseconds"3 days from now", "elapsed time" — durations
timehour / minute / second (no date)Time-of-day only, e.g. "business hours 9:00 to 18:00"
Doing Date Arithmetic with the datetime Library
date(2024, 3, 15)create+ timedelta(days=3)date(2024, 3, 18)result+ timedelta= new date
date + timedelta gives you a new date. The difference date2 - date1 returns a timedelta.
from datetime import date, datetime, timedelta

# Create a date
order_date = date(2024, 3, 15)
print(order_date)            # 2024-03-15

# Three days later
delivery = order_date + timedelta(days=3)
print(delivery)              # 2024-03-18

# The gap between two dates is a timedelta
elapsed = delivery - order_date
print(elapsed.days)          # 3

# Current time
now = datetime.now()
print(now.year, now.month, now.day)

datetime.now and Environment Dependence

datetime.now() returns the current time of the machine running the code, so the value changes every run whether you're on the browser's Pyodide runtime or a real machine. Practice exercises use a fixed date(2024, 3, 15) to keep things reproducible — try now() separately in the console to see how it behaves.

Compute the ship date (3 days later) and the pay due date (14 days later) from order date 2024-03-15.

① Import date and timedelta from datetime, then build the order date date(2024, 3, 15).

② Compute ship date = order date + timedelta(days=3) and pay due = order date + timedelta(days=14).

③ Print both as Ship date: ... and Pay due: ....

Python Editor

Run code to see output

Computing the Gap Between Two Dates

Subtracting one date from another returns a timedelta object. The .days attribute gives you just the day count, so questions like "how many days until X?" have a clean integer answer.

Compute how many days separate the ship date and the pay due from Practice 1.

① Recreate the same order date, ship date, and pay due as in Practice 1.

② Compute pay_due - ship_date to get a timedelta, then read its .days attribute.

③ Print the day count as Interval: ... days.

Python Editor

Run code to see output

strftime / strptime — Converting Between Dates and Strings

Dates inside files, logs, or JSON almost always arrive as strings. In Python, strftime (format time) turns datetime → string, and strptime (parse time) turns string → datetime. Both take a format code that maps symbols to meanings — %Y is a 4-digit year, %m is a 2-digit month, and so on.

The Symmetry of strftime and strptime
datetimeobjectstring'2024-03-15'format codes like %Y-%m-%ddatetimeobjectstring'2024-03-15'strftime (format)strptime (parse)
strftime writes a datetime out using a format string; strptime reads a string back in with the same format. The f is for format, the p is for parse. Format codes (%Y, %m, %d, etc.) are shared between the two.
Format codeMeaningExample
%Y4-digit year2024
%m2-digit month (01-12)03
%d2-digit day (01-31)15
%H2-digit 24-hour hour (00-23)14
%M2-digit minute (00-59)30
%S2-digit second (00-59)00
%AWeekday name (English)Friday
%wWeekday number (0=Sun, 6=Sat)5
from datetime import datetime

# string -> datetime
text = "2024-03-15 14:30:00"
dt = datetime.strptime(text, "%Y-%m-%d %H:%M:%S")
print(dt.year, dt.month, dt.day)   # 2024 3 15

# datetime -> string
dt2 = datetime(2024, 3, 15, 14, 30)
print(dt2.strftime("%Y/%m/%d"))               # 2024/03/15
print(dt2.strftime("%Y-%m-%d %H:%M"))          # 2024-03-15 14:30

Format Mismatches Raise ValueError

If the separators in your string don't match the format code — for example strptime("2024/03/15", "%Y-%m-%d") — you get a ValueError. Look at the actual format of your input data and align hyphens with hyphens, slashes with slashes. For ISO-style strings like "2024-03-15T14:30:00" that mix dashes with a T and colons, datetime.fromisoformat(text) is easier.

Convert the log timestamp string "2024-03-15 14:30:45" into a datetime object, then reformat it differently.

① Import the datetime class from the datetime module.

② Store the timestamp string above in a variable.

Parse the string into a datetime object (the format code mirrors the layout of the input). Then print Type: datetime using type(value).__name__.

④ Pull year, month, and day off the datetime as attributes (d.year / d.month / d.day) and print them as Year: ... Month: ... Day: ....

⑤ Format the same datetime into year/month/day hour:minute (drop the seconds). Print the formatted value's type as Formatted type: str with type(formatted).__name__, then print the value as Formatted: ... (confirming it went datetime → str).

Python Editor

Run code to see output

time and calendar — Measuring Elapsed Time and Inspecting Months

The time module is separate from datetime and exposes lower-level time APIs. The one you'll reach for most is time.perf_counter(), a high-resolution counter that returns the current elapsed time in seconds (as a float). Call it twice — before and after — and the difference is your execution time. The calendar module pulls calendar information like how many days a month has or the weekday of the first of the month.

When to Use time.time vs time.perf_counter
time.time()Unix timestamp (seconds)time.perf_counter()monotonic counterlog timestampswhen absolute time mattersexecution timingwhen relative time is enough
time.time returns seconds since 1970-01-01 00:00 UTC (a Unix timestamp). time.perf_counter is a high-precision monotonic counter with an unspecified zero — perfect for measuring elapsed time.
FunctionReturnsUse case
time.time()Unix timestamp (float)Current-time timestamps
time.perf_counter()monotonic counter (float, seconds)Measuring execution time
calendar.monthrange(y, m)(weekday of first day, last day) tupleMonth calendar information
calendar.isleap(y)True / FalseLeap year check
import time
import calendar

# Measure execution time
start = time.perf_counter()
total = sum(range(100000))
elapsed = time.perf_counter() - start
print("Total:", total)
print("Type:", type(elapsed).__name__)   # float

# Calendar info
weekday, last_day = calendar.monthrange(2024, 2)   # (weekday of first day, last day)
print("Last day of Feb 2024:", last_day)
print("Leap year:", calendar.isleap(2024))

Why Use perf_counter Instead of time.time

time.time() returns a Unix timestamp (seconds with a fraction), but if the machine's clock gets adjusted backwards by NTP, the difference can go negative. time.perf_counter() is guaranteed to be monotonic (always increasing) and is purpose-built for elapsed-time measurement, so for stopwatch-style timing it's the right choice every time.

Combine elapsed-time measurement with month info.

① Import time and calendar.

② Start a stopwatch (use the high-precision counter for elapsed time).

③ Sum the integers from 0 through 49999.

④ Compute the elapsed time and print Total: ... and Elapsed >= 0 seconds: True (real wall time varies by environment, so we just confirm it's non-negative).

⑤ Print the last day of February 2024 as Feb end: ... days and the leap-year check as Leap year: True / False.

Python Editor

Run code to see output

time.sleep — Pausing for a Set Interval

`time.sleep(seconds)` is a function that pauses execution for the given number of seconds. It shows up everywhere — retry intervals, rate limiting, animation timing. The argument is a float, so you can pass fractions like time.sleep(0.5). Since these exercises run in the browser, keep sleeps short (0–1 second) to verify behavior.

Stop execution with `time.sleep` and check whether the elapsed time is at least 0.3 seconds. Real wall time wobbles a little by environment, so we verify it as a boolean — was it at least 0.3 seconds?

① Import time.

② Record the start time with time.perf_counter().

③ Wait 0.3 seconds with time.sleep(0.3).

④ Compute elapsed time as time.perf_counter() - start_time and print Elapsed >= 0.2 seconds: True / False using >= 0.2.

(If you run it correctly the explanation appears below.)

Python Editor

Run code to see output
QUIZ

Knowledge Check

Answer each question one by one.

Q1Which combination computes "3 days from now"?

Q2Which format string converts the string "2024/03/15" into a datetime?

Q3Which is best for measuring execution time?

Q4What's the simplest way to turn the ISO 8601 string "2024-03-15T14:30:00" into a datetime?