Koordynowanie zdarzeń globalnych za pomocą Temporal

Funkcje internetowe: Temporal

Planowanie wydarzeń w różnych strefach czasowych jest bardzo trudne w przypadku starszego obiektu Date, zwłaszcza w okresie zmiany czasu na letni, gdy godziny mogą być pomijane lub powtarzane.

Interfejs API Temporal udostępnia Temporal.ZonedDateTime do reprezentowania daty i godziny w określonej strefie czasowej, automatycznie i przewidywalnie obsługując zmiany czasu letniego.

Jak to zrobić?

Aby koordynować wydarzenia globalne i rozwiązywać potencjalne konflikty związane z czasem letnim:

  1. OBOWIĄZKOWE: utwórz ZonedDateTime: użyj Temporal.ZonedDateTime.from(), aby utworzyć obiekt daty i godziny uwzględniający strefę czasową.
  2. OBOWIĄZKOWE: obsługa niejednoznaczności: użyj opcji disambiguation, aby kontrolować działanie, gdy czas jest niejednoznaczny lub nie istnieje (np. podczas zmiany czasu).
  3. OBOWIĄZKOWE: Konwertowanie stref czasowych: użyj .withTimeZone(), aby zobaczyć odpowiednik czasu w innej lokalizacji.

Przykład: planowanie i wykrywanie konfliktów

// 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' })}`);

Strategiczne wdrażanie i sprawdzone metody

  • UŻYWAJ Temporal.ZonedDateTime w przypadku wydarzeń, które są powiązane z określonym położeniem geograficznym (np. spotkanie w określonym mieście).
  • UŻYWAJ disambiguation: 'reject', jeśli chcesz wykrywać konflikty w harmonogramie podczas przejścia na czas letni i ostrzegać o nich użytkowników.
  • DO use disambiguation: 'compatible' (the default) when you want the system to automatically pick a sensible time when conflicts occur.
  • NIE używaj Temporal.PlainDateTime w przypadku wydarzeń globalnych, ponieważ nie zawiera on informacji o strefie czasowej i nie uwzględnia zmian czasu letniego.
  • UŻYWAJ .withTimeZone() do obliczania równoważnego czasu w innych lokalizacjach bez zmieniania oryginalnego obiektu (obiekty Temporal są niezmienne).
  • UŻYWAJ natywnego formatowania .toLocaleString() (np. { hour: 'numeric', minute: '2-digit' }) do wyświetlania czasu dla użytkownika zamiast ręcznych obliczeń i dopełniania.

Strategia zastępcza

Zastępcze rozwiązania i obsługa Temporal w przeglądarkach

W przypadku przeglądarek, które nie obsługują jeszcze natywnego interfejsu API Temporal, użyj wykrywania funkcji i dynamicznie wczytaj temporal-polyfill (~15 KB min+gz).

Pamiętaj, że zaimportowanie temporal-polyfill nie powoduje automatycznego przypisania obiektu Temporal do zakresu globalnego. Przypisz go bezpośrednio, jeśli Twój kod opiera się na globalThis.Temporal.

// 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();
})();