Client-Zeitzone vom Browser abrufen

138

Gibt es eine zuverlässige Möglichkeit, eine Zeitzone vom Client-Browser abzurufen? Ich habe die folgenden Links gesehen, möchte aber eine robustere Lösung.

Automatische Erkennung einer Zeitzone mit JavaScript

Zeitzonenerkennung in JavaScript

Konfuzius
quelle
8
Ich habe jsTimezoneDetect geschrieben, auf das Sie oben verweisen, und ich gehe davon aus, dass es mit reinem browserübergreifendem Javascript (ohne Geolocation und IP-Lookups) so nah wie möglich ist.
Jon Nylander
1
Mögliches Duplikat von Erhalten der Zeitzone des Kunden in JavaScript
Suma

Antworten:

87

Schauen Sie sich diese Repository- Seite an, es ist hilfreich

Laden Sie jstz.min.js herunter und fügen Sie Ihrer HTML-Seite eine Funktion hinzu

<script language="javascript">
    function getTimezoneName() {
        timezone = jstz.determine()
        return timezone.name();
    }
</script>

und rufen Sie diese Funktion von Ihrem Display-Tag aus auf

Georgischer Staatsbürger
quelle
13
TL; DR Wir können jetzt Intl.DateTimeFormat().resolvedOptions().timeZone(kein IE11) verwenden, wie von Wallace vorgeschlagen.
Code4R7
194

Ein halbes Jahrzehnt später haben wir einen eingebauten Weg dafür! Für moderne Browser würde ich verwenden:

const tz = Intl.DateTimeFormat().resolvedOptions().timeZone;
console.log(tz);

Dies gibt eine IANA-Zeitzonenzeichenfolge zurück, jedoch nicht den Offset . Weitere Informationen finden Sie in der MDN-Referenz .

Kompatibilitätstabelle - Stand März 2019: Funktioniert für 90% der weltweit verwendeten Browser. Funktioniert nicht mit Internet Explorer .

Wallace
quelle
4
funktioniert nicht in Firefox: Intl.DateTimeFormat().resolvedOptions().timeZone->undefined
Tomas Tomecek
3
Firefox und IE scheinen die Eigenschaft nicht zu unterstützen :( developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
Wallace
5
Intl.DateTimeFormat().resolvedOptions().timeZonewird den erwarteten Wert ab Firefox 52 zurückgeben: kangax.github.io/compat-table/esintl/…
julen
Wie benutzt man dieses Formular? In einem versteckten Wert, wie auf developer.mozilla.org/en-US/docs/Web/HTML/Element/input/… vorgeschlagen ?
Henry
4
Funktioniert jetzt in Firefox
Dustin Michels
74

Wenn Menschen nach "Zeitzonen" suchen, reicht oft nur "UTC-Offset" aus. Ihr Server befindet sich beispielsweise in UTC + 5 und sie möchten wissen, dass ihr Client in UTC-8 ausgeführt wird .


In einfachem altem Javascript (new Date()).getTimezoneOffset()/60wird die aktuelle Anzahl der von UTC versetzten Stunden zurückgegeben.

Es ist erwähnenswert, dass im Zeichen des getTimezoneOffset()Rückgabewerts (aus MDN-Dokumenten) ein mögliches "Gotcha" angegeben ist :

Der Zeitzonenversatz ist die Differenz in Minuten zwischen UTC und Ortszeit. Beachten Sie, dass dies bedeutet, dass der Offset positiv ist, wenn die lokale Zeitzone hinter UTC liegt, und negativ, wenn sie voraus ist. Für die Zeitzone UTC + 10: 00 (australische Ost-Standardzeit, Wladiwostok-Zeit, Chamorro-Standardzeit) werden beispielsweise -600 zurückgegeben.


Ich empfehle jedoch, die Datei day.js für zeit- / datumsbezogenen Javascript-Code zu verwenden. In diesem Fall können Sie einen nach ISO 8601 formatierten UTC-Offset erhalten, indem Sie Folgendes ausführen:

> dayjs().format("Z")
"-08:00"

Es ist wahrscheinlich zu erwähnen, dass der Kunde diese Informationen leicht fälschen kann.

(Hinweis: Diese Antwort empfahl ursprünglich https://momentjs.com/ , aber dayjs ist eine modernere, kleinere Alternative.)

Chris W.
quelle
30
Es kann erwähnenswert sein, dass Versatz und Zeitzone nicht unbedingt dasselbe sind.
Dex
9
Wie würden Sie die Sommerzeit nur mit dem Versatz anwenden? In diesem Bereich ist der Offset ein halbes Jahr falsch. IMO ist die Zeitzone genauer.
Savageman
4
Die Sommerzeit ist zu jedem Zeitpunkt Teil des Versatzes. Die mitteleuropäische Zeit im Winter ist UTC + 01: 00. Wenn jedoch die Sommerzeit angewendet wird, ist MEZ UTC + 02: 00, so wie es jetzt in Dänemark ist, wo ich bin.
Gert Sønderby
1
Aus diesem Grund benötigt getTimezoneOffset () ein Datum, an dem gearbeitet werden muss - es wird die zu diesem Zeitpunkt gültige Sommerzeit hinzugefügt.
OsamaBinLogin
2
Der Versatz ist nicht genau, wenn die Sommerzeit berücksichtigt wird.
Greg L.
48

Im Moment ist die beste Wette wahrscheinlich jstz, wie in der Antwort von mbayloon vorgeschlagen .

Der Vollständigkeit halber sollte erwähnt werden, dass es einen Standard auf dem Weg gibt: Intl . Sie können dies bereits in Chrome sehen:

> Intl.DateTimeFormat().resolvedOptions().timeZone
"America/Los_Angeles"

(Dies entspricht nicht dem Standard, was ein weiterer Grund ist, bei der Bibliothek zu bleiben.)

Johannes Hoff
quelle
1
Intl sieht in allem außer Safari stabil aus. caniuse.com/#feat=internationalization
Michael Cole
2
@MichaelCole Konforme Implementierungen von Intlsollen undefinedfür die timeZoneEigenschaft zurückgegeben werden, wenn Sie beim Erstellen der nicht manuell eine Zeitzone angegeben haben DateTimeFormat. Chrome weicht vom Standard ab, indem stattdessen die Zeitzone des Systems zurückgegeben wird. Das ist es, was Johannes 'Antwort ausnutzt, aber auch, warum er sagte, "folgt nicht wirklich dem Standard".
Chris Jester-Young
19
FYI -.. Der Standard ist jetzt Intl.DateTimeFormat () resolvedOptions () timezone
Nederby
4

Sie können die Zeitzone verwenden, um die Zeitzone zu erraten:

> moment.tz.guess()
"America/Asuncion"
Tomas Tomecek
quelle
4

Hier ist eine jsfiddle

Es enthält die Abkürzung für die aktuelle Benutzerzeitzone.

Hier ist das Codebeispiel

var tz = jstz.determine();
console.log(tz.name());
console.log(moment.tz.zone(tz.name()).abbr(new Date().getTime()));
Pushkar Newaskar
quelle
1
Um das Datum so anzuzeigen, wie May 22 2015 03:45 PM CDT ich es verwendet habe console.log(moment(now).format('MMM DD YYYY hh:mm A') + ' ' + moment.tz.zone(tz.name()).abbr(now.getTime()));
αƞjiβ
5
Ihre Geige funktioniert nicht mehr und gibt Fehler in der Konsole aus.
Saumil
2

Ich habe einen ähnlichen Ansatz wie Josh Fraser verwendet , der den Browser-Zeitversatz von UTC bestimmt und feststellt, ob die Sommerzeit erkannt wird oder nicht (aber etwas vereinfacht aus seinem Code):

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

Beim Laden wird die ClientTZ.getBrowserTZ()Funktion ausgeführt, die Folgendes festlegt:

  • ClientTZ.UTCoffset zum Browser-Zeitversatz von UTC in Minuten (z. B. beträgt CST –360 Minuten, was –6,0 Stunden von UTC entspricht);
  • ClientTZ.UTCoffsetTauf den Versatz in der Form '±hhmmD'(z. B. '-0600D'), wobei das Suffix Dfür DST und Sfür Standard (Nicht-DST) steht;
  • ClientTZ.hasDST (zu wahr oder falsch).

Das ClientTZ.UTCoffsetwird in Minuten statt in Stunden angegeben, da einige Zeitzonen gebrochene stündliche Offsets haben (z. B. +0415).

Die Absicht dahinter ClientTZ.UTCoffsetTist, es als Schlüssel für eine Tabelle von Zeitzonen (hier nicht bereitgestellt) zu verwenden, z. B. für eine Dropdown- <select>Liste.

David R Tribble
quelle
Es sieht so aus, als würde immer "D" zurückgegeben, wenn Sommerzeit beobachtet wird. Und warum nur fünf Monate Unterschied? Sicherlich werden Jan und Juli zuverlässiger arbeiten?
Matt
@Matt - Ja, Sie können 7-1für Juli anstelle von Juni verwenden. Ich bin mir nicht sicher, ob es wirklich einen Unterschied macht, da ich bezweifle, dass es regionale Sommerzeitprogramme gibt, die den Juni nicht einschließen.
David R Tribble
-13

Nein, es gibt keinen einzigen zuverlässigen Weg und es wird niemals einen geben. Haben Sie wirklich gedacht, Sie könnten dem Kunden vertrauen?

Florian Margaine
quelle
23
Zur Verdeutlichung: Die Uhr des Kunden ist möglicherweise nicht richtig eingestellt, oder er versucht böswillig, Sie zu täuschen, dass er sich in einer anderen Zeitzone als der tatsächlichen befindet. Wenn Sie die Zeitzone des Kunden verwenden möchten, tun Sie dies nicht für wichtige Zwecke.
Ryan Kinal
7
-1 für eine möglicherweise irreführende Antwort und keine Klärung.
Doug S
6
Ja, für meine Bewerbung kann ich dem Kunden vertrauen. Wenn der Client falsch konfiguriert wurde oder einen Fehler aufweist, liegt dies an meinen Benutzern.
Michael Cole
3
Ich stimme Florian tatsächlich zu. Zuverlässige Methode? So'ne Art. Verlässliche Daten? Auf keinen Fall.
Rob
4
Die Frage sagt nicht, wie die Daten verwendet werden. Beispielsweise heißt es nicht, dass die erkannte Zeitzone jemals an einen Server gesendet wird. Die Bemerkung zum Vertrauen ist daher irrelevant, wenn die Daten rein lokal verwendet werden.
Dolmen