Angenommen, Sie haben eine Zeit, die Sie auf Ihrer Website anzeigen möchten. Sie haben sie in Ihrer Zeitzone eingegeben. Sie können immer spezifisch sein und etwas sagen wie: 15:00 Uhr Osteuropäische Zeit. Dann überlassen Sie es dem Leser, dies in seine lokale Zeit umzuwandeln. Jede Zeitzone ist eine großartige Website dafür.
Aber es kann schön sein, die Zeit für den Leser zu lokalisieren. Zeitzonenkonvertierung ist notorisch verwirrend. Und es ist die Art von Sache, die Computer gut können. JavaScript weiß schließlich, in welcher Zeitzone sich der Leser befindet.
Ich bin mir sicher, dass es dafür eine Reihe von Möglichkeiten gibt. Ich musste es kürzlich bei einem neuen Projekt tun und folgte Dave Ruperts Beispiel, der es auf der Website von ShopTalk implementiert hat, um die lokalisierte Zeit für unsere nächste Live-Show anzuzeigen.
Bibliotheken
Moment.js und Moment Timezone sind ein Paar, das dies erledigen kann. Und wenn Sie andere aufwendigere Datums- und Zeitmanipulationen oder relative Berechnungen (z. B. „vor 32 Minuten“, „12. August 2015“) durchführen müssen, sind Sie mit diesen Bibliotheken gut bedient.
Wir müssen auch die Zeitzone selbst erkennen, und glücklicherweise gibt es eine Bibliothek dafür.
Wir werden also verwenden
- jstz.js
- moment.js
- moment-timezone.js
Binden Sie diese Pakete oder Links nach Belieben ein.
Schritt 1: Zeitzone ermitteln
Am besten legen Sie sie nach dem Ermitteln im localStorage ab. Das erfordert beim nächsten Abruf weniger Aufwand für den Browser.
if (!sessionStorage.getItem('timezone')) {
var tz = jstz.determine() || 'UTC';
sessionStorage.setItem('timezone', tz.name());
}
var currTz = sessionStorage.getItem('timezone');
Schritt 2: Zeitwert erhalten
Moment erwartet einen Datums-/Zeitwert (in UTC) wie
2015-08-12T14:30Z
Wenn wir nur an der Uhrzeit interessiert sind, können wir den Datumsteil dieses Strings von Moment für das heutige Datum erstellen (das macht die Formatierung einfach viel einfacher). Das Datum spielt tatsächlich eine Rolle wegen UGHGKGJHGH Sommerzeit.
var date = moment().format("YYYY-MM-DD");
Dann erstellen wir den endgültigen String, vorausgesetzt, wir haben eine Variable mit der gewünschten Zeit
var stamp = date + "T" + theTime + "Z";
Und wandeln ihn in ein Moment-Objekt um
var momentTime = moment(stamp);
Schritt 3: Zeit lokalisieren
Jetzt können wir diese Zeit mit Moment Timezone anpassen/lokalisieren
var tzTime = momentTime.tz(currTz);
Und sie für die Anzeige richtig formatieren
var formattedTime = tzTime.format('h:mm A');
Schritt 4: Verwenden
Jetzt können wir sie überall auf der Seite platzieren. Wenn Sie auch die Zeitzone ausgeben, könnten Sie sogar die aktuell auf der Seite ausgegebene Zeit ersetzen, da sie bei einem Fehler bei der Zeitzonenerkennung auf UTC zurückfällt und diese als Zeitzone ausgibt.
output.textContent = "Time in " + currTz + ": " + formattedTime;
Zeiten anpassen
Manchmal ist es sinnvoll (vielleicht aus CMS-Sicht), die Leute aufzufordern, die Zeit in einer lokalen Zeitzone einzugeben. Aber um die Konvertierung korrekt durchzuführen, ist es sinnvoller, diese Zeit in UTC zu haben.
Moment selbst kann bei der Anpassung von Zeiten helfen, z. B.
moment().subtract(4, 'hours');
moment().add(3, 'hours');
Serverseitige Sprachen können ebenfalls helfen. Zum Beispiel kann PHP Berechnungen mit Zeiten durchführen
<?php var $sixHoursAgo = strtotime("-6 hours", time()); ?>
Das macht wahrscheinlich am meisten Sinn mit Moment Timezone, da es nicht immer eine exakte Formel ist (wieder UGHADKGHK Sommerzeit).
Demo
In dieser Demo verwenden wir eine HTML5-Zeiteingabe und passen sie im Handumdrehen an eine lokalisierte Zeit an.
Sehen Sie den Stift Zeiten an lokale Zeitzonen anpassen von Chris Coyier (@chriscoyier) auf CodePen.
Andere Wege
Haben Sie Erfahrungen damit? Wie haben Sie es gehandhabt?
Die hier verwendeten Abhängigkeiten sind nicht unerheblich! Es scheint, dass native JavaScript-Methoden (z. B. getTimezoneOffset()) eine ziemlich gute Unterstützung haben, die für ähnliche Zwecke verwendet werden könnte. Haben Sie Erfahrungen mit der Nutzung dieser?
Das ist ziemlich gut, ich hätte nie gedacht, dass man das clientseitig machen kann. Zumindest kann ich jetzt einige Beiträge per AJAX abrufen und ihre Zeit für deren lokale Umgebung konvertieren.
Moment++
Es war eine große Hilfe bei meinem aktuellen Projekt, dessen Großteil ein Reservierungssystem ist, das viel Datums- und Zeitlogik erfordert.
jstz versucht, die Zeitzone anhand des Offsets zu ermitteln, kann dies aber nicht zuverlässig tun – es kann mehrere Zeitzonen geben, die einem Offset entsprechen.
Benutzerinteraktion erforderlich – der Benutzer muss bestätigen, dass die automatisch ausgewählte Zeitzone die richtige ist.
Sie sollten Ihre Speicherfunktion in einen try-catch-Block einpacken, um Probleme mit dem privaten Browsing von Safari zu vermeiden.
Sie erwähnen „localStorage“ im Artikel, verwenden aber „sessionStorage“ im Beispiel; letzteres ist korrekt, da es abläuft. Der Grund dafür ist, dass sich die Zeitzone natürlich ändern kann, z. B. durch Wechsel des physischen Standorts oder automatisch, z. B. mit BST/GMT in Großbritannien.
Sie brauchen keine Bibliothek, um das zu tun!
JavaScript-Daten wurden ursprünglich dafür entwickelt, in lokaler Zeit zu arbeiten, und später erweitert, um UTC zu unterstützen. Das bedeutet, dass Sie Zeiten einfach ohne Bibliothek konvertieren können, solange Sie sie in Ihrem Code in UTC speichern (und Sie sollten wirklich alle Datumsangelegenheiten überall in UTC haben und sie nur bei der Anzeige lokalisieren).
http://codepen.io/Merri/pen/EjJbyw
Wenn Sie Moment bereits mehrfach verwenden, sodass mehr seiner Funktionen genutzt werden, dann halte ich es für ganz in Ordnung. Aber für diesen speziellen Fall ist es sicherlich übertrieben.
Ich dachte schon darüber nach, die lokalen Zeitmethoden des Date-Objekts zu erwähnen.
Das Einzige, was Ihr Beispiel „fehlen“ lässt, ist der tatsächliche Name der Zeitzone; während Chris' Beispiel mir sagte, dass es die Zeit „in Europa/Berlin“ ist – aber brauche ich diese Information wirklich? Normalerweise weiß ich doch, in welcher Zeitzone ich mich befinde, oder?
Also drei (zusätzliche) Bibliotheken für so wenig Wirkung? Das erscheint mir awfully aufgebläht und eine Verschwendung von Ressourcen.
Zeigt meine Zeit ist 16:30 – es ist 07:30
Seltsamerweise kann ich meinen StackOverflow-Post nicht mehr finden. Ich erinnere mich, dass ich mich mit der Anzeige von Daten befasst habe, die fast 2 Jahrzehnte zurücklagen, als die Sommerzeitregeln hier anders waren. Ich hatte Schwierigkeiten zu verstehen, warum die Zeit für die Anzeige falsch zu sein schien. Es stellte sich heraus, dass die Stunde aufgrund von Sommerzeitregeln, die zur Zeit der Entwicklung galten, nicht existierte...JS dachte, es sei eine gute Idee, die aktuellen Sommerzeitregeln Ihres Systems unabhängig vom Jahr zu akzeptieren. Wenn ich mich richtig erinnere, ist dies Teil der Spezifikation, damit Browser das Problem nicht beheben. Interessanterweise rundete Node.js (zu dieser Zeit glaube ich 0.10-0.11) die nicht existierende Stunde anders als die Browser, hurra für Konsistenz :P
Ich glaube, dies war mein Fiddle, das ich für den Browser in der fehlenden StackOverflow-Frage verlinkt habe
Native Date(): http://jsfiddle.net/ybnhfmer/1/
Mit MomentJS: http://jsfiddle.net/ybnhfmer/
Die Zeitzone ist Neuseeland. Sie müssen wahrscheinlich Ihre Zeitzone anpassen, um den Fehler zu sehen. Die Sommerzeitdaten finden Sie hier: http://www.timeanddate.com/time/change/new-zealand/auckland?year=1998
Es gibt die Konsole aus
DATUM :So 27. Sep 1998 03:55:19 GMT+1300 (Neuseeländische Sommerzeit), OFFSET: -780, TIMESTAMP: 906821719000Aber offensichtlich liegt die Zeit um eine Stunde daneben, was sie sein sollte. Zufälligerweise ist dieser Tag der Beginn der Sommerzeit im Jahr 2015: http://www.timeanddate.com/time/change/new-zealand/auckland?year=2015
Ich musste ähnliche Dinge für ein Projekt im Zusammenhang mit den Olympischen Spielen tun, bei dem die Zeitzone des Benutzers, die Zeitzone der olympischen Veranstaltungen und die Zeitzonen der Server, auf denen diese Website lief, auf ärgerliche Weise miteinander interagierten. Wir stellten fest, dass die einfachste Lösung darin bestand, dass Datumsangaben/Zeiten im vom Server generierten HTML in der Zeitzone des Servers geliefert und dann auf der Client-Seite in der Zeitzone des Geräts des Benutzers neu formatiert wurden.
Was dies jedoch einfacher zu verwalten machte, war die Verwendung von Datenattributen zum Speichern eines JS-kompatiblen Datumsstrings. So lieferten unsere Server in New York
<span data-datetime="2015-08-18T18:30:00.000Z">18. August, 14:30 Uhr EDT</span>, aber ein Benutzer in Kalifornien sah18. August, 11:30 Uhr. Das Attribut ermöglichte es uns, alle Datumsangaben, die formatiert werden mussten, mit einer einfachen CSS-Abfrage abzurufen, und der Wert wurde ohne String-Manipulation geparst.Wir hatten Moment.js noch nicht, als wir dieses Projekt durchführten, aber das hätte das Leben viel einfacher gemacht. Eine native Browserfunktion
Intl.DateTimeFormatwäre noch besser gewesen, und glücklicherweise ist das jetzt fast Realität.Ich habe das für eine Chatbox gemacht, die über ein TamperMonkey-Userscript in eine Website eingebettet wurde, das einen Zeitstempel (wie
new Date()) von einem Node.js-WebSocket-Server abrief, und ich habe diese Funktion verwendet, um die Zeit auf dem Client in die Zeitzone des Benutzers zu konvertieren.Ich arbeite derzeit mit moment.js, moment-timezone.js & jstz.js, um Analysedaten auf eine bestimmte Zeitzone zu lokalisieren. Sie können Ihre updateTime-Funktion wie folgt vereinfachen:
Standardmäßig parst Moment das Datum, setzt das Datum auf jetzt und überschreibt es mit dem Datum, das es empfängt. Sie können es hier in Aktion sehen: http://codepen.io/gbergeron/pen/RWbJaX