Globale Ereignisse mit Temporal koordinieren

Webfunktionen: Temporal

Das Planen von Ereignissen in verschiedenen Zeitzonen ist mit dem alten Date-Objekt bekanntermaßen schwierig, insbesondere bei der Umstellung auf die Sommerzeit, wenn Stunden übersprungen oder wiederholt werden können.

Die Temporal API bietet Temporal.ZonedDateTime, um ein Datum und eine Uhrzeit in einer bestimmten Zeitzone darzustellen, wobei die Umstellung auf Sommerzeit automatisch und vorhersehbar erfolgt.

Implementierung

So koordinieren Sie globale Ereignisse und gehen mit potenziellen Konflikten bei der Sommerzeit um:

  1. OBLIGATORISCH: ZonedDateTime erstellen: Verwenden Sie Temporal.ZonedDateTime.from(), um ein zeitzonenabhängiges Datum-Uhrzeit-Objekt zu erstellen.
  2. OBLIGATORISCH: Mehrdeutigkeit behandeln: Verwenden Sie die Option disambiguation, um das Verhalten zu steuern, wenn eine Zeit mehrdeutig ist oder nicht existiert (z.B. bei Zeitumstellungen).
  3. OBLIGATORISCH: Zeitzonen umrechnen: Verwende .withTimeZone(), um die entsprechende Zeit an einem anderen Ort zu sehen.

Beispiel: Planung und Konflikterkennung

// 1. Define the event time and target time zone
const date = "2025-03-09";
const time = "02:30"; // This time is skipped in New York during Spring Forward
const timeZone = "America/New_York";
const inputStr = `${date}T${time}[${timeZone}]`;

// 2. Detect conflicts using 'reject'
let hasConflict = false;
try {
  // 'reject' throws RangeError if the time is ambiguous or does not exist
  Temporal.ZonedDateTime.from(inputStr, { disambiguation: 'reject' });
} catch (e) {
  if (e instanceof RangeError) {
    hasConflict = true;
    console.log("This time falls in a DST transition gap or overlap.");
  }
}

// 3. Resolve the time safely using 'compatible' (default)
// 'compatible' will resolve to a valid time even if skipped or repeated
const hostTime = Temporal.ZonedDateTime.from(inputStr, { disambiguation: 'compatible' });
console.log(`Resolved time: ${hostTime.toString()}`);

// 4. Convert to another time zone (e.g., Tokyo)
const tokyoTime = hostTime.withTimeZone("Asia/Tokyo");
// Use toLocaleString() for user-facing display instead of manual hour/minute padding
console.log(`Tokyo time: ${tokyoTime.toLocaleString('en-US', { hour: 'numeric', minute: '2-digit' })}`);

Strategische Implementierung und Best Practices

  • Verwenden Sie Temporal.ZonedDateTime für Ereignisse, die an einen bestimmten geografischen Standort gebunden sind (z. B. eine Besprechung in einer bestimmten Stadt).
  • DO use disambiguation: 'reject' if you need to detect and warn users about scheduling conflicts during DST transitions.
  • VERWENDEN Sie disambiguation: 'compatible' (Standard), wenn das System bei Konflikten automatisch einen sinnvollen Zeitpunkt auswählen soll.
  • Verwenden Sie Temporal.PlainDateTime NICHT für globale Ereignisse, da es keine Zeitzoneninformationen enthält und keine Änderungen der Sommerzeit berücksichtigt.
  • VERWENDEN Sie .withTimeZone(), um die entsprechende Zeit an anderen Orten zu berechnen, ohne das ursprüngliche Objekt zu verändern (Temporal-Objekte sind unveränderlich).
  • DO: Verwenden Sie für die für Nutzer sichtbare Zeitanzeige die native .toLocaleString()-Formatierung (z. B. { hour: 'numeric', minute: '2-digit' }) anstelle von manuellen Zeitberechnungen und Padding.

Fallback-Strategie

Fallbacks und Browserunterstützung für Temporal

Für Browser, die die native Temporal API noch nicht unterstützen, können Sie die Funktionserkennung verwenden und temporal-polyfill dynamisch laden (~15 KB min+gz).

Beachten Sie, dass das Importieren von temporal-polyfill das Temporal-Objekt nicht automatisch dem globalen Bereich zuweist. Weisen Sie ihn explizit zu, wenn Ihr Code auf globalThis.Temporal basiert.

// Check if Temporal is supported natively
(async () => {
  if (typeof Temporal === 'undefined') {
    // Load the polyfill conditionally
    const module = await import('https://esm.sh/temporal-polyfill');
    globalThis.Temporal = module.Temporal;
    // Extend Date.prototype if needed
    Date.prototype.toTemporalInstant = module.toTemporalInstant;
  }
  initializeApp();
})();