Om een publicatiedatum en benoemde tijdzone om te zetten naar een exact moment om middernacht, bepaal je de lokale tijd 00:00:00 met de regels van die zone, controleer je of die tijd bestaat en zet je die vervolgens om naar UTC. Deze Terminal-werkwijze voor Mac detecteert ook herhaalde middernachten.

Stel dat een synthetisch publicatierecord de datum 2025-07-15 en de zone America/New_York bevat. Je taak is de tijdstempel te berekenen die middernacht aan het begin van die datum weergeeft. De onderstaande werkwijze levert een tijdstempel op die je kunt kopiëren naar een tool die UTC accepteert, terwijl de oorspronkelijke datum en zone zichtbaar blijven om ze te controleren.

Welke informatie bepaalt een moment om middernacht?

Houd deze vier waarden gedurende de hele berekening gescheiden:

Waarde Synthetisch voorbeeld Betekenis
Burgerlijke datum 2025-07-15 Een Gregoriaanse kalenderdatum zonder tijd of zone
Lokale datum en tijd 2025-07-15T00:00:00 De gevraagde kloktijd
Benoemde tijdzone America/New_York De regels waarmee die lokale tijd wordt geïnterpreteerd
Bepaald moment 2025-07-15T04:00:00Z Eén specifiek moment uitgedrukt in UTC

Python geeft een kalenderdatum weer met date, combineert datum- en tijdvelden met datetime en gebruikt tijdzonegegevens om een tijdzonebewuste datetime te interpreteren. De klasse timezone geeft vaste offsets weer; zoneinfo levert regels voor benoemde tijdzones. Zie de officiële datetime-documentatie en zoneinfo-documentatie.

Een offset zoals -04:00 is het verschil tussen de lokale tijd en UTC voor een bepaalde tijd. Een benoemde zone levert regels die op verschillende datums verschillende offsets kunnen opleveren. RFC 9557 legt uit waarom het vervangen van een benoemde zone door een vaste offset kan leiden tot onjuiste vervolgcalculaties. Behoud de zonenaam in plaats van een offset uit een ander publicatierecord over te nemen. RFC 9557: Datum en tijd op internet: tijdstempels met aanvullende informatie

Voor deze taak betekent ‘middernacht’ precies 00:00:00 aan het begin van de opgegeven datum. Maak deze vereiste expliciet voordat je iets berekent: voor een verzoek om het eerste geldige moment van een kalenderdag is een ander beleid nodig wanneer middernacht ontbreekt.

Waarom moet je middernacht controleren voordat je de tijd omzet?

Lokale klokveranderingen kunnen een gat veroorzaken, waarin een kloktijd niet voorkomt, of een herhaling, waarin een kloktijd twee keer voorkomt. PEP 495 van Python definieert deze gevallen en biedt het attribuut fold om herhaalde tijden te onderscheiden. Ook wordt uitgelegd dat constructors en replace() ontbrekende lokale tijden niet automatisch afwijzen. Een zone koppelen valideert de gevraagde middernacht dus op zichzelf niet. PEP 495 – Onderscheid maken tussen lokale tijden

Gebruik de volgende beslisregel voor een publicatievereiste die exact middernacht voorschrijft:

Gevonden geldige momenten om middernacht Interpretatie Actie
Eén Middernacht komt één keer voor Geef dat moment terug
Twee Middernacht komt twee keer voor Wijs af totdat een keuze voor eerder/later is gemaakt
Geen Exact middernacht ontbreekt Meld dat met deze invoer niet aan de vereiste kan worden voldaan

Het onderstaande programma voert deze regel uit door beide fold-waarden te proberen, elke kandidaat naar UTC om te zetten en die vervolgens terug te zetten naar de benoemde zone. Een kandidaat blijft alleen over als de teruggegeven lokale velden exact overeenkomen met de gevraagde middernacht. Dubbele UTC-resultaten worden samengevoegd tot één kandidaat. Deze validatiestappen zijn afgeleid van het gedocumenteerde gedrag van tijdconversie en folds; het gaat om aanvullende applicatielogica. datetime.astimezone(), PEP 495

Hoe voer je de berekening uit in Terminal op een Mac?

Open Spotlight, typ Terminal en open de app. Je kunt ook /Applications/Utilities openen in Finder en dubbelklikken op Terminal. Dit zijn de door Apple gedocumenteerde manieren om een opdrachtvenster te openen. Terminal openen of afsluiten op de Mac

Voer de volgende opdracht uit om je Python-versie te controleren:

python3 --version

Dit voorbeeld vereist Python 3.9 of hoger, waarin zoneinfo beschikbaar kwam. Als Python ontbreekt of ouder is, volg je de officiële installatiehandleiding voor macOS om een momenteel ondersteund Python-installatieprogramma van Python.org te verkrijgen. Controleer daarna opnieuw de versie. De werkwijze gebruikt modules uit de standaardbibliotheek. zoneinfo — IANA-tijdzoneondersteuning, Python gebruiken op macOS

Kopieer het hele onderstaande blok naar Terminal en druk op Return. Het is een volledige opdracht met het Python-programma. Als je een andere publicatietijdstempel wilt berekenen, pas je DATE_TEXT en ZONE_NAME aan voordat je het blok plakt. Laat REPEATED op reject staan, tenzij je bewust een beleid voor herhaalde middernacht hebt gekozen.

python3 - <<'PY'
from datetime import date, datetime, time, timezone
from zoneinfo import ZoneInfo, ZoneInfoNotFoundError

DATE_TEXT = '2025-07-15'
ZONE_NAME = 'America/New_York'
REPEATED = 'reject'  # 'reject', 'earlier', or 'later'


def resolve_midnight(date_text, zone_name, repeated='reject'):
    if repeated not in {'reject', 'earlier', 'later'}:
        raise ValueError('Repeated-time policy must be reject, earlier, or later.')

    day = date.fromisoformat(date_text)
    if day.isoformat() != date_text:
        raise ValueError('Use a date in YYYY-MM-DD format.')

    zone = ZoneInfo(zone_name)
    wall = datetime.combine(day, time.min)
    candidates = set()

    for fold in (0, 1):
        guess = wall.replace(tzinfo=zone, fold=fold)
        instant = guess.astimezone(timezone.utc)
        back = instant.astimezone(zone)
        if back.replace(tzinfo=None) == wall:
            candidates.add(instant)

    ordered = sorted(candidates)
    if not ordered:
        raise ValueError('Exact midnight does not exist on this date in this zone.')

    if len(ordered) == 2 and repeated == 'reject':
        choices = ', '.join(x.isoformat() for x in ordered)
        raise ValueError(
            'Midnight repeats. Choose earlier or later. UTC choices: ' + choices
        )

    chosen = ordered[-1] if repeated == 'later' else ordered[0]
    return chosen.astimezone(zone), chosen


try:
    local, utc = resolve_midnight(DATE_TEXT, ZONE_NAME, REPEATED)
except ZoneInfoNotFoundError:
    raise SystemExit(
        'Zone not found. Check the IANA name and time zone data installation.'
    )
except (ValueError, OverflowError) as exc:
    raise SystemExit(str(exc))

print('Civil date:', DATE_TEXT)
print('Named zone:', ZONE_NAME)
print('Local midnight:', local.isoformat())
print('UTC instant:', utc.isoformat().replace('+00:00', 'Z'))
PY

Voor het opgegeven voorbeeld is de uitvoer:

Burgerlijke datum: 2025-07-15
Benoemde zone: America/New_York
Lokale middernacht: 2025-07-15T00:00:00-04:00
UTC-moment: 2025-07-15T04:00:00Z

Lees de twee tijdstempelregels samen. De lokale regel bevestigt dat de gevraagde kloktijd middernacht is. De UTC-regel geeft hetzelfde moment aan: als je de lokale offset van min vier uur aftrekt, krijg je 04:00:00 UTC. RFC 3339 definieert een tijdstempel met een datum, tijd en een numerieke offset of Z. RFC 3339: Datum en tijd op internet: tijdstempels

Hoe controleer je gewone en uitzonderlijke resultaten?

De volgende invoerwaarden zijn synthetische publicatievoorbeelden die zijn geselecteerd om het programma te testen. De resultaten zijn berekend met de bovenstaande resolver en de beschikbare tijdzonedatabase; het zijn geen gegevens van echte publicaties. Wijzig de twee invoerwaarden en voer de volledige opdracht voor elk geval opnieuw uit.

Datum Benoemde zone Resultaat van de resolver
2025-01-15 America/New_York Eén moment: 2025-01-15T05:00:00Z
2025-07-15 America/New_York Eén moment: 2025-07-15T04:00:00Z
2018-11-04 America/Sao_Paulo Exacte middernacht ontbreekt; wordt afgewezen
2020-11-01 America/Havana Middernacht komt twee keer voor; standaard afgewezen
2011-12-30 Pacific/Apia Exacte middernacht ontbreekt; wordt afgewezen

De eerste twee rijen laten zien waarom de datum onderdeel is van de berekening: in dezelfde benoemde zone wordt middernacht omgezet naar verschillende UTC-uren. Voor het voorbeeld met de herhaalde middernacht in Havana selecteert REPEATED = 'earlier' 2020-11-01T04:00:00Z; als je dit instelt op later, wordt 2020-11-01T05:00:00Z geselecteerd. De namen verwijzen naar de chronologische volgorde op de UTC-tijdlijn.

Bij een ontbrekende middernacht moet je een beslissing nemen over de publicatievereiste. Als exact middernacht essentieel is, kies dan expliciet een andere datum of zone. Als je eigenlijk de eerste geldige tijd op die datum bedoelt, definieer en implementeer die bewerking afzonderlijk, inclusief wat er moet gebeuren als de hele datum ontbreekt. Deze resolver meldt bewust een fout in plaats van ongemerkt een andere lokale tijd te gebruiken.

Wat moet je doen als een invoerwaarde een fout oplevert?

Bij een datumfout geef je een echte Gregoriaanse datum op in de vorm YYYY-MM-DD, zoals 2025-07-15. Het programma controleert zowel of de datum op de kalender bestaat als of de opmaak exact klopt. Een invoer zoals 2025-02-30 levert een fout op in plaats van naar een andere maand te worden doorgeschoven.

Controleer bij Zone not found de volledige IANA-aanduiding, inclusief spelling en hoofdletters. Python documenteert dat deze uitzondering zowel een ongeldige sleutel als ontbrekende tijdzonegegevens kan betekenen. Python zoekt standaard eerst in systeemgegevens en gebruikt daarna het door de eerste partij onderhouden pakket tzdata als terugvaloptie. Als de gegevens ontbreken, installeer je dat pakket in de Python-omgeving die je gebruikt en voer je de resolver opnieuw uit. PEP 615 – Ondersteuning voor de IANA-tijdzonedatabase in de standaardbibliotheek

Bewaar de oorspronkelijke datum, zonenaam, keuze bij een herhaalde tijd en de bepaalde UTC-tijdstempel samen in je aantekeningen. Als berekeningen op verschillende computers uiteenlopen, vergelijk dan hun bronnen voor tijdzonegegevens. Het installeren van een terugvalpakket vervangt niet automatisch de systeemgegevens die Python al vindt. zoneinfo-gegevensbronnen

Welke waarde moet je naar een andere tool kopiëren?

Als de bestemming een UTC-tijdstempel accepteert, kopieer je de waarde UTC-moment, inclusief Z. Controleer de gedocumenteerde invoerindeling van de bestemming voordat je de waarde invoert. Een gewoon datumveld kan niet alle informatie behouden die in die bepaalde tijdstempel is vastgelegd; bewaar de oorspronkelijke datum en benoemde zone erbij als je de geplande bedoeling wilt behouden.

RFC 9557 definieert een uitgebreide tijdstempelindeling die een achtervoegsel met een benoemde zone kan bevatten, maar ook die indeling geeft een bepaald moment weer. De standaard erkent ook dat updates van zonegegevens inconsistenties kunnen veroorzaken tussen opgeslagen offsets en zonegegevens. Gebruik een uitgebreide weergave alleen als de ontvangende tool ondersteuning daarvoor documenteert. RFC 9557, reikwijdte en inconsistente offsets

Controleer tot slot of de lokale uitvoer de bedoelde datum op 00:00:00 toont, of de benoemde zone overeenkomt met je invoer en of je een eventuele keuze bij herhaalde middernacht bewust hebt gemaakt. Zodra deze controles zijn geslaagd, is de UTC-uitvoer het bepaalde moment van middernacht volgens de regels die bij die berekening zijn gebruikt.

Bronnen