Python standaardbibliotheek voor datum en tijd: de datetime module volledig onder de knie krijgen

Serie 03 – Datum-/tijdbewerkingen, tijdzones, formaatconversie in één overzicht

Tijd is niet zomaar een “string”. Dagen verlopen, maanden veranderen, zomertijd speelt een rol en elke regio heeft zijn eigen tijdzone. 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 rekening te houden met tijdzones.

Tijdwerker in een magische werkplaats

In dit artikel focussen we ons op de datetime module en behandelen we:

  • Het aanmaken van de 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-dag
  • time : alleen uur:minuut:seconde
  • datetime : datum + tijd (meest gebruikt)
  • timedelta : het “verschil” tussen twee tijden (periode)
  • timezone : vaste offset tijdzone (bijv. UTC+9)

Vanaf Python 3.9 is zoneinfo aan de standaardbibliotheek 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 in 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 staat 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 met dagen, seconden en microseconden. Een uitdrukking als “een maand later” kan met timedelta(days=30) benaderd worden, maar voor kalenderspecifieke 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 formaatpatronen:

  • %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 je astimezone().


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 verandert
  • astimezone(...): hetzelfde moment wordt omgezet naar een andere tijdzone

6. Veelvoorkomende valkuilen

6.1 Naïef/aware mengen

  • Gebruik voor interne berekeningen 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 het parsen van strings

strptime faalt zelfs bij 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 specifiek moment

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 van tijd een berekenbare waarde. Door tijdzones (timezone, zoneinfo) te integreren, kun je code schrijven die robuust blijft, ongeacht de omgeving.

In het volgende artikel behandelen we random en bespreken we het genereren van willekeurige getallen, sampling, shuffling, seeding en veilige willekeurigheid (secrets).


Gerelateerde artikelen


Bekijk eerdere series