Esiste un modo affidabile per ottenere un fuso orario dal browser del client? Ho visto i seguenti link ma voglio una soluzione più solida.
Esiste un modo affidabile per ottenere un fuso orario dal browser del client? Ho visto i seguenti link ma voglio una soluzione più solida.
Risposte:
Guardate questo repository pageloom è utile
scarica jstz.min.js e aggiungi una funzione alla tua pagina html
<script language="javascript">
function getTimezoneName() {
timezone = jstz.determine()
return timezone.name();
}
</script>
e chiama questa funzione dal tuo tag display
Intl.DateTimeFormat().resolvedOptions().timeZone
(no IE11) come suggerito da Wallace.
Mezzo decennio più tardi abbiamo un modo integrato per farlo! Per i browser moderni utilizzerei:
const tz = Intl.DateTimeFormat().resolvedOptions().timeZone;
console.log(tz);
Ciò restituisce una stringa di fuso orario IANA, ma non l'offset . Ulteriori informazioni al riferimento MDN .
Tabella di compatibilità : a partire da marzo 2019, funziona per il 90% dei browser in uso a livello globale. Non funziona su Internet Explorer .
Intl.DateTimeFormat().resolvedOptions().timeZone
->undefined
Intl.DateTimeFormat().resolvedOptions().timeZone
restituirà il valore atteso a partire da Firefox 52: kangax.github.io/compat-table/esintl/…
Spesso quando le persone sono alla ricerca di "fusi orari", sarà sufficiente solo "offset UTC". ad esempio, il loro server è in UTC + 5 e vogliono sapere che il loro client è in esecuzione in UTC-8 .
In javascript semplicemente (new Date()).getTimezoneOffset()/60
restituirà il numero attuale di offset offset da UTC.
Vale la pena notare un possibile "gotcha" nel segno del getTimezoneOffset()
valore restituito (dai documenti MDN) :
La differenza di fuso orario è la differenza, in minuti, tra l'ora UTC e l'ora locale. Si noti che ciò significa che l'offset è positivo se il fuso orario locale è dietro UTC e negativo se è avanti. Ad esempio, per il fuso orario UTC + 10: 00 (Ora solare dell'Australia orientale, Ora di Vladivostok, Ora standard di Chamorro), verrà restituito -600.
Tuttavia, ti consiglio di usare day.js per il codice Javascript relativo a ora / data. In tal caso è possibile ottenere un offset UTC formattato ISO 8601 eseguendo:
> dayjs().format("Z")
"-08:00"
Vale probabilmente la pena ricordare che il cliente può facilmente falsificare queste informazioni.
(Nota: questa risposta originariamente raccomandava https://momentjs.com/ , ma dayjs è un'alternativa più moderna e più piccola.)
Per ora, la scommessa migliore è probabilmente jstz come suggerito nella risposta di mbayloon .
Per completezza, va detto che c'è uno standard sulla sua strada: Intl . Puoi vederlo già in Chrome:
> Intl.DateTimeFormat().resolvedOptions().timeZone
"America/Los_Angeles"
(Questo in realtà non segue lo standard, che è un motivo in più per attenersi alla libreria)
Intl
dovrebbero essere restituite undefined
per la timeZone
proprietà se non hai specificato manualmente un fuso orario nella costruzione di DateTimeFormat
. Chrome si discosta dallo standard restituendo invece il fuso orario del sistema; questo è ciò che sfrutta la risposta di Johannes, ma anche perché ha detto "in realtà non segue lo standard".
puoi usare il fuso orario per indovinare il fuso orario:
> moment.tz.guess()
"America/Asuncion"
Ecco un jsfiddle
Fornisce l'abbreviazione del fuso orario dell'utente corrente.
Ecco l'esempio di codice
var tz = jstz.determine();
console.log(tz.name());
console.log(moment.tz.zone(tz.name()).abbr(new Date().getTime()));
May 22 2015 03:45 PM CDT
ho usato console.log(moment(now).format('MMM DD YYYY hh:mm A') + ' ' + moment.tz.zone(tz.name()).abbr(now.getTime()));
Ho usato un approccio simile a quello adottato da Josh Fraser , che determina il time offset del browser rispetto a UTC e se riconosce l'ora legale o meno (ma in qualche modo semplificato dal suo codice):
var ClientTZ = {
UTCoffset: 0, // Browser time offset from UTC in minutes
UTCoffsetT: '+0000S', // Browser time offset from UTC in '±hhmmD' form
hasDST: false, // Browser time observes DST
// Determine browser's timezone and DST
getBrowserTZ: function () {
var self = ClientTZ;
// Determine UTC time offset
var now = new Date();
var date1 = new Date(now.getFullYear(), 1-1, 1, 0, 0, 0, 0); // Jan
var diff1 = -date1.getTimezoneOffset();
self.UTCoffset = diff1;
// Determine DST use
var date2 = new Date(now.getFullYear(), 6-1, 1, 0, 0, 0, 0); // Jun
var diff2 = -date2.getTimezoneOffset();
if (diff1 != diff2) {
self.hasDST = true;
if (diff1 - diff2 >= 0)
self.UTCoffset = diff2; // East of GMT
}
// Convert UTC offset to ±hhmmD form
diff2 = (diff1 < 0 ? -diff1 : diff1) / 60;
var hr = Math.floor(diff2);
var min = diff2 - hr;
diff2 = hr * 100 + min * 60;
self.UTCoffsetT = (diff1 < 0 ? '-' : '+') + (hr < 10 ? '0' : '') + diff2.toString() + (self.hasDST ? 'D' : 'S');
return self.UTCoffset;
}
};
// Onload
ClientTZ.getBrowserTZ();
Al caricamento, ClientTZ.getBrowserTZ()
viene eseguita la funzione che imposta:
ClientTZ.UTCoffset
alla differenza di tempo del browser da UTC in minuti (ad esempio, CST è −360 minuti, che è −6,0 ore da UTC);ClientTZ.UTCoffsetT
all'offset nella forma '±hhmmD'
(ad es. '-0600D'
), dove il suffisso è D
per l'ora legale e S
per l' ora legale (non l'ora legale);ClientTZ.hasDST
(vero o falso).Il ClientTZ.UTCoffset
è previsto in pochi minuti anziché ore, perché alcuni fusi orari hanno offset orarie frazionali (ad esempio, +0415).
L'intento dietro ClientTZ.UTCoffsetT
è quello di usarlo come chiave in una tabella di fusi orari (non fornita qui), come per un <select>
elenco a discesa .
7-1
luglio invece di giugno. Non sono sicuro che faccia davvero la differenza, dal momento che dubito che ci siano schemi regionali di ora legale che non includono giugno.
No. Non esiste un unico modo affidabile e non ci sarà mai. Pensavi davvero di poterti fidare del cliente?