Menu

Python datetime: Dates, Times, Timedeltas, and Timezones

A practical tour of Python's datetime module — parsing, formatting, doing math on dates, and handling timezones without getting lost.

The Two Core Types: date and datetime

The datetime module gives you four things worth knowing: date, time, datetime, and timedelta. The first three are what they sound like; the fourth is a span of time.

main.py
Output
Click Run to see the output here.

A date represents a day — year, month, day — with no clock attached. A datetime is a date plus a time. If you don't need the clock, date is the tidier choice.

Creating Specific Dates

Construct directly:

main.py
Output
Click Run to see the output here.

Arguments are year, month, day for date, and up to year, month, day, hour, minute, second, microsecond for datetime.

Reading Fields

Every date/datetime has attributes:

main.py
Output
Click Run to see the output here.

isoformat() is your friend for machine-readable output — it produces something like "2026-04-20T09:30:15" that other systems can parse unambiguously.

Formatting With strftime

For human-readable output, .strftime(fmt) turns a date or datetime into a formatted string:

main.py
Output
Click Run to see the output here.

The format codes most often worth remembering:

  • %Y — 4-digit year (2026)
  • %m — month number, zero-padded (04)
  • %d — day of month, zero-padded (20)
  • %H / %I — hour, 24/12 hour format
  • %M — minute
  • %S — second
  • %A / %a — weekday name full / abbreviated (Monday / Mon)
  • %B / %b — month name full / abbreviated (April / Apr)
  • %p — AM/PM

You don't need to memorize them; bookmark a reference and look them up when you need one.

Parsing With strptime

The reverse direction: take a string with a known shape and turn it into a datetime:

main.py
Output
Click Run to see the output here.

The format string must match the input exactly. If it doesn't, strptime raises ValueError.

For ISO-8601 strings (the machine-readable standard), there's a simpler shortcut in modern Python:

main.py
Output
Click Run to see the output here.

If you're dealing with random formats, the external dateutil package (pip install python-dateutil) has a forgiving parser.parse() that takes a reasonable guess.

Arithmetic With timedelta

To do math on dates, use timedelta for the difference or offset:

main.py
Output
Click Run to see the output here.

timedelta arguments: days, seconds, microseconds, milliseconds, minutes, hours, weeks. No months or years — months are variable length. For month/year math, use dateutil.relativedelta:

from dateutil.relativedelta import relativedelta
from datetime import date

today = date.today()
next_quarter = today + relativedelta(months=3)
print(next_quarter)

Timezones: Naive vs Aware

A datetime without timezone info is naive — Python doesn't know what timezone it represents. Time math on naive datetimes is fine as long as you stay within one logical timezone; the trouble starts the moment data from different zones meets.

An aware datetime carries timezone info with it. Attach a timezone explicitly:

main.py
Output
Click Run to see the output here.

Python 3.9 added the zoneinfo module for named timezones (using the system's IANA database):

main.py
Output
Click Run to see the output here.

Convert between zones with .astimezone():

main.py
Output
Click Run to see the output here.

A rule worth committing to memory: store datetimes in UTC, convert to local zones only at display time. That one habit prevents most timezone bugs.

Timestamps

A Unix timestamp is the number of seconds since 1970-01-01 UTC. Python converts easily:

main.py
Output
Click Run to see the output here.

Timestamps are useful for comparisons, sorting, and interop with other systems. For human-facing output, convert back to a datetime first.

Measuring How Long Something Takes

For quick timings, subtract two datetimes:

main.py
Output
Click Run to see the output here.

For more serious performance measurement, use time.perf_counter() — it has sub-microsecond resolution and is immune to system clock changes. datetime.now() is fine for "how long did this API call take" style numbers.

Patterns You'll Reuse

main.py
Output
Click Run to see the output here.

What to Take Away

  • date, datetime, and timedelta cover 90% of needs.
  • Use ISO-8601 for machine-readable; strftime for human-readable.
  • Store in UTC; convert at display time.
  • Use zoneinfo for named timezones.
  • For months and years, reach for dateutil.relativedelta.

One more tool for your real-world toolkit: regular expressions, up next.

Frequently Asked Questions

How do I get the current date and time in Python?

datetime.now() returns the current local date-and-time. datetime.utcnow() returns UTC (though the modern preference is datetime.now(timezone.utc) since utcnow() returns a naive datetime). For just the date, use date.today().

How do I format a date as a string?

Use .strftime(format) with format codes like %Y-%m-%d for year-month-day. Example: datetime.now().strftime('%Y-%m-%d %H:%M'). To parse a string back, use datetime.strptime(text, format) with the same format codes.

How do I add days to a date in Python?

Use timedelta: from datetime import date, timedelta; date.today() + timedelta(days=7). timedelta supports days, hours, minutes, seconds, weeks, and more. For month and year math, use the external dateutil.relativedeltatimedelta doesn't know about months.

Learn to code with Coddy

GET STARTED