Skip to content
Foxipa

Suggest an edit

Tell us what should be corrected, clarified, or improved. Submission will be connected to Foxipa’s contribution service later.

No information is sent anywhere yet. Your suggestion is only prepared in your browser.

Learning

Working with Dates and Times

Use Python's datetime types for dates, clock times, durations, parsing, formatting, and timezone-aware values.

Levels: Intermediate ~24 min read

Intermediate

A date, a clock time, a date-and-time value, and a duration represent different things. Python’s datetime module provides date, time, datetime, and timedelta types so you can calculate with calendar values instead of relying on loosely formatted strings.

Choose the right date/time type

Use date for a calendar day, time for a wall-clock time without a date, datetime for a combined value, and timedelta for a difference or duration. Construct values from their components when those components are already available.

Interactive Runnable example
Edit

Ready to run.

Quick check

Which type represents a calendar day without a clock time?

from datetime import date
print(date(2026, 10, 12).isoformat())

Calculate with durations

Adding or subtracting a timedelta produces a new date or datetime; the original value is unchanged. Subtracting two dates gives a timedelta. A timedelta stores days, seconds, and microseconds, not calendar months or years, so a month should not be treated as a fixed number of days.

Interactive Runnable example
Edit

Ready to run.

Quick check

What is the result of subtracting one date from another?

from datetime import date
first = date(2026, 10, 12)
second = date(2026, 10, 19)
print((second - first).days)

Parse and format deliberately

Use fromisoformat() for supported ISO 8601 date/time strings, isoformat() for a stable machine-readable representation, strptime() when an input follows a known explicit format, and strftime() for display formatting. Parsing can fail; catch ValueError at the input boundary when malformed user data is expected.

Interactive Runnable example
Edit

Ready to run.

Quick check

Which method parses text that follows a specified format string?

from datetime import datetime
parsed = datetime.strptime("12/10/2026", "%d/%m/%Y")
print(parsed.date().isoformat())

Distinguish naive and aware datetimes

A naive datetime has no usable timezone offset and cannot identify a unique instant by itself. An aware datetime has timezone information that supplies an offset. Comparing a naive datetime with an aware one raises TypeError. For timestamps that represent real-world instants, prefer aware values and state the timezone explicitly.

Interactive Runnable example
Edit

Ready to run.

Quick check

What happens when a naive datetime is ordered against an aware datetime?

from datetime import datetime, timezone
naive = datetime(2026, 10, 12)
aware = datetime(2026, 10, 12, tzinfo=timezone.utc)
try:
    naive < aware
except TypeError as error:
    print(type(error).__name__)

Use UTC and named time zones

datetime.now(timezone.utc) produces an aware current UTC value. For a real geographic timezone, use zoneinfo.ZoneInfo and convert an aware instant with astimezone(). Do not use replace(tzinfo=...) as a conversion: it attaches timezone metadata without converting the clock fields. ZoneInfo uses the system IANA timezone database; platforms without that data may need the first-party tzdata package. Regional offsets can change with daylight-saving rules, so avoid hard-coding a fixed offset for a named place.

Interactive Runnable example
Edit

Ready to run.

Quick check

Which operation converts an aware datetime to another timezone?

from datetime import datetime, timezone
from zoneinfo import ZoneInfo
instant = datetime(2026, 7, 15, 12, tzinfo=timezone.utc)
paris = instant.astimezone(ZoneInfo("Europe/Paris"))
print(paris.strftime("%H:%M %z"))

Keep calendar rules separate from elapsed time

A calendar day and 24 elapsed hours are not always interchangeable when timezone transitions are involved. For elapsed-time measurements, compare aware instants after converting both to UTC. For a recurring local appointment, preserve its local wall-clock intent and use a named timezone. Repeated or nonexistent local times around daylight-saving changes need an explicit policy; ZoneInfo supports the fold attribute for ambiguous times.

Interactive Runnable example
Edit

Ready to run.

Key takeaways

  • Use date for a calendar day, time for a clock reading, datetime for a combined value, and timedelta for a duration.
  • Use ISO parsing/formatting for well-defined interchange and explicit format strings for other input/display formats.
  • Prefer aware datetime values for real instants; use timezone.utc and ZoneInfo rather than guessing regional offsets.
  • Local wall-clock scheduling and elapsed-time measurement are different problems around timezone transitions.

Quick check recap

Check your understanding by selecting the right type for a calendar value, calculating a date difference, parsing a timestamp, explaining the naive/aware comparison rule, and converting an instant to a named timezone. Finish with the programming challenge and quiz.

Was this page helpful?

Mark this learning resource complete to track your learning progress.