La pianificazione di eventi in fusi orari diversi è notoriamente difficile con l'oggetto Date precedente, in particolare durante le transizioni dell'ora legale, quando le ore possono essere saltate o ripetute.
L'API Temporal fornisce Temporal.ZonedDateTime per rappresentare una data e un'ora in un fuso orario specifico, gestendo le transizioni dell'ora legale in modo automatico e prevedibile.
Modalità di implementazione
Per coordinare gli eventi globali e gestire i potenziali conflitti relativi all'ora legale:
- OBBLIGATORIO: crea un ZonedDateTime: utilizza
Temporal.ZonedDateTime.from()per creare un oggetto data-ora che tiene conto del fuso orario. - OBBLIGATORIO: Gestisci ambiguità: utilizza l'opzione
disambiguationper controllare il comportamento quando un orario è ambiguo o non esiste (ad esempio, durante i cambi di orario). - MANDATORY: Convert Time Zones: Use
.withTimeZone()to see the equivalent time in another location.
Esempio: pianificazione e rilevamento dei conflitti
// 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' })}`);
Implementazione strategica e best practice
- SÌ: utilizza
Temporal.ZonedDateTimeper gli eventi legati a una posizione geografica specifica (ad esempio una riunione in una città specifica). - SÌ: utilizza
disambiguation: 'reject'se devi rilevare e avvisare gli utenti di conflitti di pianificazione durante le transizioni dell'ora legale. - CONSIGLIATO: utilizza
disambiguation: 'compatible'(impostazione predefinita) se vuoi che il sistema scelga automaticamente un orario ragionevole quando si verificano conflitti. - NON utilizzare
Temporal.PlainDateTimeper gli eventi globali, in quanto non contiene informazioni sul fuso orario e non può tenere conto delle modifiche dell'ora legale. - SÌ: utilizza
.withTimeZone()per calcolare l'ora equivalente in altre località senza modificare l'oggetto originale (gli oggetti Temporal sono immutabili). - SÌ: utilizza la formattazione
.toLocaleString()nativa (ad esempio{ hour: 'numeric', minute: '2-digit' }) per la visualizzazione dell'ora rivolta agli utenti anziché i calcoli e la spaziatura manuali dell'ora.
Strategia di riserva
Fallback e supporto del browser per Temporal
Per i browser che non supportano ancora l'API Temporal nativa, utilizza il rilevamento delle funzionalità e carica dinamicamente temporal-polyfill (~15 kB min+gz).
Tieni presente che l'importazione di temporal-polyfill non assegna automaticamente l'oggetto Temporal all'ambito globale. Assegnalo esplicitamente se il tuo codice si basa su 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();
})();