Python standaardbibliotheek voor tijd: de datetime module volledig beheersen
Serie 03 – Datum/tijd bewerkingen, tijdzones, format conversie in één keer
Tijd is niet zomaar een “string”. Dagen verlopen, maanden veranderen, zomertijd komt in beeld en elke regio heeft zijn eigen referentie. Bij het werken met datum/tijd is het dus cruciaal om een onderscheid te maken tussen een weergave‑string en een berekenbare tijdwaarde, en om tijdzones mee te nemen.

In dit artikel focussen we op de datetime module en behandelen we:
- Het maken van huidige datum en tijd
- Het berekenen van periodes (
timedelta) - Het formatteren en parsen van strings (
strftime,strptime) - Het omgaan met tijdzones (
timezone,zoneinfo) - Veelvoorkomende valkuilen en betrouwbare patronen
1. Wat biedt datetime?
datetime bevat verschillende types die op het eerste gezicht vergelijkbaar lijken, maar verschillende rollen vervullen.
date: alleen jaar‑maand‑dagtime: alleen uur:minuut:secondedatetime: datum + tijd (meest gebruikt)timedelta: het “verschil” tussen twee tijden (periode)timezone: vaste offset tijdzone (bijv. UTC+9)
Vanaf Python 3.9 is de standaardbibliotheek zoneinfo toegevoegd, waardoor het werken met regionale tijdzones (bijv. Asia/Tokyo) eenvoudiger wordt.
2. De huidige tijd verkrijgen: naive vs aware
2.1 Naive / aware
datetime objecten zijn in twee categorieën te verdelen.
- naive datetime: geen tijdzone‑informatie
- aware datetime: bevat tijdzone‑informatie (
tzinfo)
Het mengen van beide types kan fouten veroorzaken of onverwachte resultaten opleveren.
2.2 Aanbevolen standaard: begin met UTC aware
Het uniformeren van opslag en berekeningen op UTC maakt veel situaties overzichtelijker.
from datetime import datetime, timezone
utc_now = datetime.now(timezone.utc) # aware (UTC)
print(utc_now)
Voor lokale tijd kun je later converteren.
from datetime import datetime, timezone
from zoneinfo import ZoneInfo
utc_now = datetime.now(timezone.utc)
tokyo_now = utc_now.astimezone(ZoneInfo("Asia/Tokyo"))
print(utc_now)
print(tokyo_now)
3. Datum/tijd berekenen: timedelta centraal
3.1 Optellen/ aftrekken
from datetime import datetime, timedelta, timezone
now = datetime.now(timezone.utc)
print(now + timedelta(days=3))
print(now - timedelta(hours=2))
3.2 Verschil tussen twee tijden
from datetime import datetime, timezone
a = datetime(2026, 1, 1, tzinfo=timezone.utc)
b = datetime(2026, 1, 10, tzinfo=timezone.utc)
delta = b - a
print(delta.days) # 9
print(delta.total_seconds()) # 777600.0
3.3 timedelta gebruiken om periodes uit te drukken
timedelta werkt in dagen, seconden en microseconden. Een uitdrukking als “een maand later” kan met timedelta(days=30) benaderd worden, maar voor kalender‑specifieke periodes is een extra tool zoals dateutil vaak nodig.
4. Formatteren en parsen: strftime / strptime
4.1 datetime → string (strftime)
from datetime import datetime, timezone
dt = datetime(2026, 1, 30, 14, 5, 0, tzinfo=timezone.utc)
print(dt.strftime("%Y-%m-%d %H:%M:%S %z"))
Veelgebruikte formatpatronen:
%Y-%m-%d: 2026-01-30%H:%M:%S: 14:05:00%z: +0000 (UTC offset)
4.2 string → datetime (strptime)
from datetime import datetime
s = "2026-01-30 14:05:00"
dt = datetime.strptime(s, "%Y-%m-%d %H:%M:%S")
print(dt)
Het resulterende dt is naïf. Voeg een tijdzone toe met replace(tzinfo=...).
from datetime import datetime, timezone
s = "2026-01-30 14:05:00"
dt = datetime.strptime(s, "%Y-%m-%d %H:%M:%S").replace(tzinfo=timezone.utc)
print(dt)
replace(tzinfo=...)wijzigt de tijd niet, het voegt alleen een tijdzone‑label toe. Voor een echte conversie gebruik jeastimezone().
5. Tijdzones: onderscheid tussen timezone en zoneinfo
5.1 Vaste offset → timezone
from datetime import datetime, timezone, timedelta
kst_fixed = timezone(timedelta(hours=9))
dt = datetime(2026, 1, 30, 12, 0, tzinfo=kst_fixed)
print(dt)
5.2 Regionale tijdzone → zoneinfo
from datetime import datetime, timezone
from zoneinfo import ZoneInfo
utc_now = datetime.now(timezone.utc)
ny_now = utc_now.astimezone(ZoneInfo("America/New_York"))
print(ny_now)
5.3 replace(tzinfo=...) vs astimezone(...)
replace(tzinfo=...): tijd blijft gelijk, alleen het label verandertastimezone(...): dezelfde instant wordt omgezet naar een andere tijdzone
6. Veelvoorkomende valkuilen
6.1 Naïf/aware mengen
- Gebruik binnenberekeningen aware (UTC) voor stabiliteit.
- Normaliseer externe invoer naar een uniforme tijdzone.
6.2 “Lokale tijd” kan variëren
datetime.now() volgt de lokale instellingen van de omgeving. In containers of servers kan de lokale tijd UTC zijn. Gebruik datetime.now(timezone.utc) voor consistentie.
6.3 Formaatfouten bij stringparsing
strptime faalt bij zelfs een klein formaatverschil. Als er meerdere invoerformaten zijn, overweeg een voorverwerking of een stap‑voor‑stap poging.
7. Drie veelgebruikte patronen
7.1 Opslaan in ISO 8601
from datetime import datetime, timezone
dt = datetime.now(timezone.utc)
print(dt.isoformat()) # bijv. 2026-01-30T05:12:34.567890+00:00
7.2 Bestandsnaam met “vandaag”
from datetime import datetime
stamp = datetime.now().strftime("%Y%m%d")
filename = f"report_{stamp}.json"
print(filename)
7.3 Tijd tot een specifieke instant
from datetime import datetime, timezone
target = datetime(2026, 2, 1, 0, 0, tzinfo=timezone.utc)
now = datetime.now(timezone.utc)
remaining = target - now
print(remaining)
print(remaining.total_seconds())
8. Afsluiting
datetime gaat verder dan het maken van datum‑strings; het maakt tijd een berekenbare waarde. Door tijdzones (timezone, zoneinfo) te integreren, kun je code schrijven die robuust blijft, ongeacht de omgeving.
In het volgende artikel scheiden we random en behandelen het genereren van willekeurige getallen, sampling, shuffling, seeding en veilige willekeur (secrets).
Gerelateerde artikelen
- Django: datetime en timezone correct gebruiken
- Django tijdbeheer – een volledige gids voor
django.utils.timezone
Bekijk eerdere series