ottenere il fuso orario del client dal browser


139

Esiste un modo affidabile per ottenere un fuso orario dal browser del client? Ho visto i seguenti link ma voglio una soluzione più solida.

Rilevamento automatico di un fuso orario con JavaScript

Rilevamento del fuso orario in JavaScript



8
Ho scritto jsTimezoneDetect a cui ti colleghi sopra, e la mia opinione sulla situazione è che è il più vicino possibile con javascript cross-browser puro (senza geolocalizzazione e ricerche IP).
Jon Nylander,

Risposte:


87

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


13
TL; DR Ora possiamo usare Intl.DateTimeFormat().resolvedOptions().timeZone(no IE11) come suggerito da Wallace.
Code4R7,

195

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 .


4
non funziona in Firefox: Intl.DateTimeFormat().resolvedOptions().timeZone->undefined
Tomas Tomecek,

3
Firefox e IE sembrano non supportare la proprietà :( developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
Wallace

5
Intl.DateTimeFormat().resolvedOptions().timeZonerestituirà il valore atteso a partire da Firefox 52: kangax.github.io/compat-table/esintl/…
julen

Come si usa questo è un modulo? In un valore nascosto come suggerito su developer.mozilla.org/en-US/docs/Web/HTML/Element/input/… ?
hendry,

4
Funziona ora con Firefox
Dustin Michels,

76

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()/60restituirà 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.)


30
Vale la pena notare che offset e fuso orario non sono necessariamente la stessa cosa.
Dex,

9
Come applicheresti l'ora legale solo con l'offset? In quell'area la compensazione è sbagliata a metà anno. IMO il fuso orario è più preciso.
Savageman,

4
L'ora legale fa parte dell'offset in qualsiasi momento. Il tempo dell'Europa centrale in inverno è UTC + 01: 00. Tuttavia, quando si applica l'ora legale, CET è UTC + 02: 00, come è ora in Danimarca dove sono.
Gert Sønderby,

1
questo è il motivo per cui getTimezoneOffset () ha bisogno di una data per funzionare - si aggiungerà all'ora legale in vigore in quel momento.
OsamaBinLogin,

2
l'offset non è preciso quando si considera l'ora legale.
Greg L.

48

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)


1
Intl sembra stabile in tutto tranne Safari. caniuse.com/#feat=internationalization
Michael Cole,

2
@MichaelCole Le implementazioni conformi di Intldovrebbero essere restituite undefinedper la timeZoneproprietà 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".
Chris Jester-Young,

20
Cordiali saluti - lo standard è ora Intl.DateTimeFormat (). ResolvedOptions (). TimeZone
Nederby


4

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

1
Per visualizzare la data che 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()));
αƞjiβ

5
Il tuo violino non funziona più e sta dando errori nella console.
Saumil,

2

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.UTCoffsetTall'offset nella forma '±hhmmD'(ad es. '-0600D'), dove il suffisso è Dper l'ora legale e Sper 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 .


Sembra che restituirà sempre 'D' se si osserva l'ora legale. E perché solo cinque mesi di differenza? Sicuramente, gennaio e luglio funzioneranno in modo più affidabile?
Matt,

@Matt - Sì, potresti usare 7-1luglio 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.
David R Tribble

-13

No. Non esiste un unico modo affidabile e non ci sarà mai. Pensavi davvero di poterti fidare del cliente?


23
Per chiarire: l'orologio del client potrebbe non essere impostato correttamente, oppure potrebbero tentare con l'inganno di farti credere di trovarsi in un fuso orario diverso da quello reale. Se hai intenzione di utilizzare il fuso orario del cliente, non farlo per qualcosa di importante.
Ryan Kinal,

7
-1 per dare una risposta potenzialmente fuorviante e non chiarire.
Doug S,

6
Sì, per la mia applicazione posso fidarmi del client. Se il client è stato configurato in modo errato o presenta un bug, ciò dipende dai miei utenti.
Michael Cole,

3
In realtà sono d'accordo con Florian. Metodo affidabile? Tipo. Dati affidabili? Sicuramente no.
Rob

4
La domanda non dice come verranno utilizzati i dati. Ad esempio, non dice che il fuso orario rilevato verrà mai inviato a un server. Pertanto, l'osservazione sulla fiducia è irrilevante se i dati vengono utilizzati esclusivamente a livello locale.
dolmen,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.