Python datetime: Work with Dates and Times

Published on: July 10, 2026
Reading time: 5 minutes
Manipulação de datas e calendário em Python

Dates and times appear in nearly every application: reports, reminders, subscriptions, logs, appointments, file names, and API payloads. They seem simple until time zones, daylight-saving changes, formatting, and calendar arithmetic enter the picture. Python’s standard datetime and zoneinfo modules provide the core tools needed to handle them clearly.

This Python datetime guide covers date, time, datetime, timedelta, parsing, formatting, time zones, comparisons, and practical patterns. It focuses on reliable application code rather than clever shortcuts.

The main datetime types

The module defines several related classes. date stores a calendar date, time stores a time of day, datetime combines both, and timedelta represents a duration. The official datetime documentation also distinguishes naive objects from timezone-aware objects.

from datetime import date, datetime, time, timedelta

today = date.today()
meeting_time = time(14, 30)
meeting = datetime(2026, 7, 10, 14, 30)
duration = timedelta(hours=1, minutes=15)

print(today)
print(meeting_time)
print(meeting + duration)

Get the current date and time

Use date.today() for a local calendar date. For an instant that may be exchanged between systems, prefer a timezone-aware datetime.

from datetime import datetime, timezone

now_utc = datetime.now(timezone.utc)
print(now_utc)

A naive datetime.now() has no timezone information. It may be acceptable for a local-only script, but it is risky for distributed systems because the value does not identify an unambiguous instant.

Create dates and datetimes

from datetime import date, datetime

release_date = date(2026, 9, 15)
deadline = datetime(2026, 9, 15, 17, 0)

print(release_date.year)
print(deadline.hour)

Constructors validate calendar rules. An impossible date, such as February 30, raises ValueError. Validate user input and provide a friendly message rather than storing malformed strings.

Format dates for people

Use strftime() to turn a date or datetime into a formatted string. Format codes represent components such as year, month, day, hour, and minute.

from datetime import datetime

moment = datetime(2026, 7, 10, 16, 45)

print(moment.strftime("%Y-%m-%d"))
print(moment.strftime("%B %d, %Y at %H:%M"))

Formatting is presentation. Keep dates as date or datetime objects during calculations and convert to text only at system boundaries or display time. The f-string formatting guide covers general output formatting.

Parse strings into datetime objects

Use strptime() when the input follows a known custom format. The format string must match the input exactly.

from datetime import datetime

text = "10/07/2026 16:45"
moment = datetime.strptime(text, "%d/%m/%Y %H:%M")

print(moment)

For ISO 8601-compatible strings, fromisoformat() is often clearer and faster to read.

from datetime import datetime

moment = datetime.fromisoformat("2026-07-10T16:45:00+00:00")
print(moment)

When parsing CSV or JSON, document the accepted format. The guides to CSV files and JSON in Python show where these conversions fit in a data pipeline.

Date arithmetic with timedelta

Add or subtract a timedelta for durations measured in days, seconds, microseconds, milliseconds, minutes, hours, or weeks.

from datetime import date, timedelta

today = date.today()
next_week = today + timedelta(weeks=1)
yesterday = today - timedelta(days=1)

print(next_week)
print(yesterday)

Subtracting two date or datetime objects returns a timedelta.

from datetime import date

start = date(2026, 7, 10)
end = date(2026, 8, 1)

difference = end - start
print(difference.days)

A timedelta is a fixed duration. “One month later” is not fixed because months have different lengths. Define the business rule explicitly or use a specialized calendar library when month arithmetic is required.

Compare dates and sort events

from datetime import datetime

events = [
    datetime(2026, 8, 1, 9, 0),
    datetime(2026, 7, 15, 14, 0),
    datetime(2026, 7, 20, 10, 30),
]

for event in sorted(events):
    print(event.isoformat())

Comparisons work naturally when objects are compatible. Do not compare a naive datetime with an aware datetime. Normalize values first. For custom record ordering, see Python sort versus sorted.

Work with time zones using zoneinfo

The standard zoneinfo module provides IANA time zone data. A named zone knows historical and daylight-saving transitions, unlike a permanently fixed numeric offset.

from datetime import datetime
from zoneinfo import ZoneInfo

sao_paulo = ZoneInfo("America/Sao_Paulo")
new_york = ZoneInfo("America/New_York")

local_meeting = datetime(2026, 7, 10, 10, 0, tzinfo=sao_paulo)
new_york_time = local_meeting.astimezone(new_york)

print(local_meeting)
print(new_york_time)

A common strategy is to store instants in UTC and convert to a user’s zone for display. Also preserve the intended named zone for recurring local events, because a fixed UTC time may not match the same wall-clock time after daylight-saving transitions.

Naive versus aware datetimes

A naive datetime has tzinfo=None. It can represent a local wall time, but the object alone does not say which location or offset applies. An aware datetime includes timezone information and represents an identifiable point on the global timeline.

from datetime import datetime, timezone

naive = datetime(2026, 7, 10, 12, 0)
aware = datetime(2026, 7, 10, 12, 0, tzinfo=timezone.utc)

print(naive.tzinfo)
print(aware.tzinfo)

Do not attach a timezone to an arbitrary naive value unless you know what zone the original wall time meant. Converting an existing instant and labeling an unzoned wall time are different operations.

Build a deadline helper

from datetime import datetime, timezone

def seconds_until(deadline: datetime) -> float:
    if deadline.tzinfo is None:
        raise ValueError("deadline must be timezone-aware")

    now = datetime.now(timezone.utc)
    normalized = deadline.astimezone(timezone.utc)
    return max(0.0, (normalized - now).total_seconds())

The function rejects ambiguous input, normalizes both values to UTC, and never returns a negative wait. Type hints make the contract visible; see Python type hints for more examples.

Use dates in file names and logs

from datetime import datetime, timezone
from pathlib import Path

timestamp = datetime.now(timezone.utc).strftime("%Y%m%dT%H%M%SZ")
path = Path("exports") / f"report-{timestamp}.txt"

path.parent.mkdir(parents=True, exist_ok=True)
path.write_text("Report created.", encoding="utf-8")

print(path)

A sortable year-month-day order keeps generated files chronological. For application events, the logging module provides configurable timestamps and structured output.

Common mistakes

  • Storing dates as inconsistent human-formatted strings.
  • Using naive datetimes for events exchanged between systems.
  • Assuming every day has exactly 24 local hours across daylight-saving transitions.
  • Treating a month as a fixed number of days.
  • Parsing user input without handling ValueError.
  • Comparing naive and timezone-aware values.
  • Using local server time as a universal reference.

Frequently asked questions

Should I store UTC in a database?

UTC is a strong default for instants such as creation times and completed transactions. For future appointments and recurring events, also store the relevant named time zone and business rules so the intended local time can be reconstructed.

What is the best date string format?

ISO 8601 is readable, sortable in many common forms, and widely supported. Include an offset or Z for instants. A bare date such as 2026-07-10 is appropriate when no time of day exists.

How do I calculate age?

Age is calendar-based, not simply elapsed days divided by 365. Compare month and day relative to the current year and define rules for leap-day birthdays.

Final thoughts

Reliable datetime code begins by deciding what a value represents: a calendar date, local wall time, duration, or global instant. Keep structured objects during calculations, use aware datetimes for exchanged instants, convert to a named zone for display, and treat calendar arithmetic as a business rule rather than a fixed-duration shortcut.

Share:

Facebook
WhatsApp
Twitter
LinkedIn

Article content

    Related articles

    Logo do Python com o texto 'requests' abaixo
    Libraries and Modules
    Foto de perfil de Leandro Hirt da Academify

    Python Requests: Complete Beginner Guide

    Learn Python Requests from scratch: install the library, send GET and POST requests, work with parameters, headers, JSON, timeouts, sessions,

    Ler mais

    Tempo de leitura: 4 minutos
    10/07/2026
    Barra de progresso com tqdm para scripts Python
    Libraries and Modules
    Foto de perfil de Leandro Hirt da Academify

    Python tqdm: Add Progress Bars to Scripts

    Add progress bars to Python scripts with tqdm. Learn installation, loops, manual updates, files, pandas, nested bars, and practical options.

    Ler mais

    Tempo de leitura: 6 minutos
    10/07/2026
    Uso do módulo random para gerar valores aleatórios em Python
    Libraries and Modules
    Foto de perfil de Leandro Hirt da Academify

    Python random Module: Complete Beginner Guide

    Learn Python's random module: generate numbers, choose items, shuffle lists, sample data, use seeds, and know when to use secrets.

    Ler mais

    Tempo de leitura: 5 minutos
    10/07/2026
    Manipulação moderna de arquivos usando pathlib em Python
    Libraries and Modules
    Foto de perfil de Leandro Hirt da Academify

    Python pathlib: Manage Files and Paths Easily

    Learn Python pathlib to create, inspect, read, write, rename, move, and delete files and folders with clean cross-platform code.

    Ler mais

    Tempo de leitura: 5 minutos
    10/07/2026
    Manipulação de arquivos e pastas usando módulo os em Python
    Libraries and Modules
    Foto de perfil de Leandro Hirt da Academify

    Python os Module: Manage Files and Folders

    Learn the Python os module to list, create, rename, move, and remove files and folders, work with paths, and read

    Ler mais

    Tempo de leitura: 5 minutos
    10/07/2026
    Uso do Counter do collections para contar elementos em Python
    Libraries and Modules
    Foto de perfil de Leandro Hirt da Academify

    Python Counter: Count Items with collections

    Learn Python Counter to count items, find common values, update totals, compare counts, and solve practical frequency problems.

    Ler mais

    Tempo de leitura: 6 minutos
    10/07/2026