Om een publicatiemoment in een andere tijdzone te formatteren, behoud je het oorspronkelijke moment en geef je de doeltijdzone mee aan de formatter. Deze handleiding voor Terminal op de Mac maakt een leesbaar publicatielabel zonder weergegeven tekst te parsen of handmatig uren op te tellen.
Welke informatie heb je nodig voordat je converteert?
Stel dat je een document voorbereidt op je Mac en de synthetische publicatietijdstempel 2025-07-15T00:30:00Z ontvangt. Je hebt de publicatiedatum en -tijd nodig zoals die wordt weergegeven in America/Los_Angeles. De taak is om hetzelfde moment weer te geven met de kalenderdatum en kloktijd van de doeltijdzone.
Vier termen bepalen of je voldoende informatie hebt:
| Term | Synthetisch voorbeeld | Betekenis voor deze taak |
|---|---|---|
| Burgerlijke datum | 2025-07-15 |
Een kalenderdag, zonder tijd of tijdzone |
| Moment | Het moment dat wordt weergegeven door 2025-07-15T00:30:00Z |
Het tijdstip dat je behoudt |
| UTC-offset | -07:00 |
Het verschil tussen lokale tijd en UTC op een bepaald moment |
| Benoemde tijdzone | America/Los_Angeles |
Regels waarmee de toepasselijke offset wordt bepaald |
RFC 3339 definieert tijdstempels met een volledige datum, tijd en UTC-offset. RFC 9557 licht het verdere onderscheid toe: een benoemde tijdzone levert regels om een moment aan een offset te koppelen, terwijl de numerieke offset van een tijdstempel op zichzelf niet beschrijft hoe de offset van een locatie zich op andere momenten gedraagt. RFC 3339, Section 5.6, RFC 9557, Section 1.2.
Gebruik deze beslisregel voor de invoer voordat je iets converteert:
- Je hebt al een Foundation-
Date: geef die rechtstreeks door aan een formatter die is ingesteld op de doeltijdzone. - Je hebt een tijdstempel met
Zof een expliciete numerieke offset: parse die oorspronkelijke tijdstempel één keer en formatteer vervolgens het resulterende moment. - Je hebt alleen een burgerlijke datum: behoud die als datum, tenzij de taak expliciet een tijd en tijdzone opgeeft.
- Je hebt een lokale datum en tijd zonder offset: achterhaal de brontijdzone en los eventuele ambiguïteit op voordat je die als een moment behandelt.
2025-07-15 vertelt je bijvoorbeeld niet of de publicatie vóór of na middernacht in een andere tijdzone heeft plaatsgevonden. Middernacht toekennen zou een aanname introduceren. Ook kan een lokale kloktijd rond een offsetovergang overeenkomen met nul of meerdere momenten; RFC 9557 beschrijft die grenssituatie. Als je een al vastgesteld moment converteert, vermijd je dit probleem van omgekeerde koppeling. RFC 9557, Section 1.2.
Waarom moet je weergegeven tekst niet opnieuw parsen?
Apple definieert Foundation's Date als een specifiek moment, onafhankelijk van een kalender of tijdzone. De waarde hoeft geen andere Date te worden om in een andere tijdzone te worden weergegeven. Formatteren levert de kalender en tijdzone die nodig zijn om tekst te maken. Date.
Een weergavelabel kan informatie weglaten. Als je een moment formatteert als een datum zonder tijd en dat label vervolgens parseert, kan de ontbrekende tijd niet uit het label worden teruggehaald. Apples documentatie over formattering toont een roundtrip met alleen een datum, waarbij middernacht opnieuw wordt opgebouwd. Dat is nuttig wanneer middernacht de bedoeling is, maar behoudt geen willekeurig publicatiemoment. Date.FormatStyle.
Houd deze volgorde aan:
- Lees de oorspronkelijke tijdstempel of haal de bestaande
Dateop. - Behoud dat moment als de waarde waarmee je werkt.
- Kies de doeltijdzone, kalender en weergavelocale.
- Formatteer het behouden moment tot het definitieve label.
Een offset handmatig optellen verandert de bewerking ook. Apple beschrijft addingTimeInterval(_:) als het maken van een nieuwe datum door verstreken tijd op te tellen. Zeven uur optellen levert dus een ander moment op; de tijdzone van een formatter kiezen verandert alleen hoe het oorspronkelijke moment wordt weergegeven. Date.
Voer een compleet voorbeeld van een publicatietijd uit op je Mac
Voor het voorbeeld is macOS 12 of hoger vereist, waarop Apples Date.FormatStyle-API beschikbaar is, en een werkende Swift-toolchain. Het gebruikt Foundation, zonder extra pakketten. Date.FormatStyle.
Open Terminal en controleer de toolchain:
swift --version
Als je Apples commandlinetools nodig hebt, voer dan de volgende opdracht uit en voltooi de installatiedialoog. Apple documenteert deze installatiemethode en vermeldt dat een volledige installatie van Xcode de commandlinetools al bevat. Voer daarna de versiecontrole opnieuw uit. De commandlinetools installeren.
xcode-select --install
Maak in Teksteditor een nieuw document en kies Opmaak > Maak platte tekst. Plak het volledige Swift-programma hieronder en bewaar het op je bureaublad als publication-time.swift. Controleer of de uiteindelijke bestandsnaam eindigt op .swift, zonder toegevoegde extensie .txt. Apples handleiding voor Teksteditor beschrijft hoe je platte-tekstdocumenten maakt, omzet en bewaart. Documenten maken, openen en omzetten in Teksteditor op de Mac.
Dit programma accepteert de opgegeven tijdstempel met hele seconden, parseert die één keer en maakt drie weergaven van dezelfde instant. Apple documenteert ISO8601DateFormatter voor het parsen en genereren van ISO 8601-weergaven en de optie withInternetDateTime voor de RFC 3339-notatie. ISO8601DateFormatter, withInternetDateTime.
import Foundation
// Synthetic publication data. Change these two values as needed.
let sourceTimestamp = "2025-07-15T00:30:00Z"
let destinationIdentifier = "America/Los_Angeles"
enum ConversionError: Error {
case invalidTimestamp(String)
case unknownTimeZone(String)
}
let inputFormatter = ISO8601DateFormatter()
inputFormatter.formatOptions = [.withInternetDateTime]
inputFormatter.timeZone = TimeZone(secondsFromGMT: 0)
guard let instant = inputFormatter.date(from: sourceTimestamp) else {
throw ConversionError.invalidTimestamp(sourceTimestamp)
}
guard let destination = TimeZone(identifier: destinationIdentifier) else {
throw ConversionError.unknownTimeZone(destinationIdentifier)
}
let destinationFormatter = ISO8601DateFormatter()
destinationFormatter.formatOptions = [.withInternetDateTime]
destinationFormatter.timeZone = destination
let publicationLabelStyle = Date.FormatStyle(
date: .long,
time: .complete,
locale: Locale(identifier: "en_GB"),
calendar: Calendar(identifier: .gregorian),
timeZone: destination
)
let publicationDateStyle = Date.FormatStyle(
date: .long,
time: .omitted,
locale: Locale(identifier: "en_GB"),
calendar: Calendar(identifier: .gregorian),
timeZone: destination
)
print("Source instant: \(inputFormatter.string(from: instant))")
print("Destination zone: \(destination.identifier)")
print("Destination timestamp: \(destinationFormatter.string(from: instant))")
print("Publication label: \(instant.formatted(publicationLabelStyle))")
print("Publication date: \(instant.formatted(publicationDateStyle))")
Voer het opgeslagen programma uit:
swift "$HOME/Desktop/publication-time.swift"
Voor de opgegeven waarden moet de doeltijdstempel 2025-07-14T17:30:00-07:00 zijn en moet de publicatiedatum 14 juli 2025 weergeven. Het leesbare label bevat ook de tijd- en tijdzonegegevens; de precieze formulering en interpunctie worden bepaald door het formatteersysteem.
Het Swift-programma is gecontroleerd aan de hand van de opgehaalde API-documentatie, maar is niet uitgevoerd in de onderzoeksomgeving omdat Swift daar niet beschikbaar was. De numerieke conversies in de voorbeelden zijn afzonderlijk gecontroleerd met de datum-, tijd- en tijdzone-API's van Python.
Welke instellingen bepalen het resultaat?
De formatterinitialisatie accepteert afzonderlijke instellingen voor locale, kalender en tijdzone. Hier vraagt en_GB om Britse Engelse formatteringsconventies, levert de Gregoriaanse kalender het datumsysteem en bepaalt destination de lokale datum en kloktijd. Wijzig de tijdzone-ID als je een andere doeltijdzone nodig hebt; wijzig de locale als je andere weergaveconventies nodig hebt. init(date:time:locale:calendar:timeZone:capitalizationContext:).
Het resultaat met alleen de datum komt nog steeds rechtstreeks van instant. Met time: .omitted wordt de tijd uit het uitvoerlabel weggelaten. Je hoeft daarvoor geen nieuw moment op middernacht te maken.
Controleer middernachtoverschrijdingen en seizoensgebonden offsets
Gebruik de volgende synthetische voorbeelden om te controleren of je resultaat de bedoelde bewerking behoudt. Dit zijn illustratieve publicatietijdstempels met berekende weergaven in de doeltijdzone.
| Oorspronkelijk moment | Doeltijdzone | Weergave in de doeltijdzone |
|---|---|---|
2025-01-15T00:30:00Z |
America/Los_Angeles |
2025-01-14T16:30:00-08:00 |
2025-07-15T00:30:00Z |
America/Los_Angeles |
2025-07-14T17:30:00-07:00 |
2025-07-15T00:30:00Z |
Asia/Tokyo |
2025-07-15T09:30:00+09:00 |
2025-07-15T23:30:00Z |
Asia/Tokyo |
2025-07-16T08:30:00+09:00 |
De eerste twee rijen laten zien waarom een vaste aanpassing niet volstaat voor een benoemde doeltijdzone: de toepasselijke offset kan afhangen van het moment. De laatste twee rijen laten zien waarom je naast de tijd ook de volledige kalenderdatum in de doeltijdzone moet bepalen. Een publicatie kan op de vorige, dezelfde of de volgende dag vallen.
Benoemde tijdzones gebruiken regels uit een tijdzonedatabase. IANA documenteert dat macOS zijn database gebruikt en dat updates doorgaans via updates van het besturingssysteem bij gebruikers terechtkomen. Als resultaten op verschillende machines afwijken, controleer dan hun tijdzone-ID's en beschikbare updates voordat je de brontijdstempel wijzigt. Gegevens over tijdzones en zomertijd.
Wat moet je doen als de invoer of uitvoer onverwacht is?
Doorloop deze controles op volgorde:
- Controleer of de bron een moment vastlegt. Behoud de
Zof numerieke offset. Een waarde met alleen een datum of een lokale kloktijd vereist aanvullende informatie. - Controleer de ID van de doeltijdzone. Gebruik een ID zoals
America/Los_Angeles. Apples initializer retourneertnilbij een onbekende ID; dit programma stopt met een foutmelding in plaats van een andere tijdzone te gebruiken. - Controleer of de tijdstempel een ondersteunde indeling heeft. Het voorbeeld is ingesteld op internettijdstempels met hele seconden. Voor fracties van seconden of een andere invoerweergave is een passende parserconfiguratie nodig. Behoud de oorspronkelijke invoer wanneer je die wijziging aanbrengt.
- Vergelijk de numerieke doeltijdstempel. Gebruik de datum, tijd en offset om de conversie te beoordelen voordat je de interpunctie van de weergave onderzoekt.
- Controleer of elke uitvoer dezelfde oorspronkelijke
instantgebruikt. Verwijder tussenstappen die een label formatteren en dat label vervolgens parsen voor de volgende conversie. init(identifier:), ISO8601DateFormatter.
Een benoemde tijdzone en een offset kunnen volgens RFC 9557 ook samen in een uitgebreide tijdstempel worden opgenomen. Het bestaan van die standaard betekent niet dat de parser in dit voorbeeld ondersteuning biedt voor de tijdzoneaanduidingen tussen vierkante haken. Bewaar de doeltijdzone-ID in de afzonderlijke waarde destinationIdentifier die hierboven wordt gebruikt, tenzij je bewust een invoerpad voor de uitgebreide notatie implementeert en controleert. RFC 9557.
Bewaar voor een publicatielabel het oorspronkelijke moment als herbruikbare waarde en genereer daaruit de tekst voor elke doeltijdzone. Zo kun je de doeltijdzone, weergavetaal of zichtbare details wijzigen, terwijl elk label naar hetzelfde publicatiemoment blijft verwijzen.
Bronnen
- Date — Apple
- Date.FormatStyle — Apple
- init(date:time:locale:calendar:timeZone:capitalizationContext:) — Apple
- ISO8601DateFormatter — Apple
- withInternetDateTime — Apple
- init(identifier:) — Apple
- De commandlinetools installeren — Apple
- Documenten maken, openen en omzetten in Teksteditor op de Mac — Apple
- RFC 3339: Datum en tijd op internet: tijdstempels — RFC Editor
- RFC 9557: Datum en tijd op internet: tijdstempels met aanvullende informatie — RFC Editor
- Gegevens over tijdzones en zomertijd — IANA