Wie kann ich mit Zeitzonen in meiner Webanwendung umgehen?

104

Ich suche nach einem besseren Verständnis der folgenden User Story:

John arbeitet in Sidney. Um 9:00 Uhr morgens protokolliert er ein Ereignis in einer Web-App, die auf einem Server in Zürich ausgeführt wird. Am nächsten Tag reist er zu einem Notfalltreffen nach New York, bei dem die Veranstaltung besprochen werden sollte. Während des Meetings sucht er nach Datum und Uhrzeit nach dem Ereignis.

Aus meiner Sicht gibt es hier mindestens zwei Probleme:

  1. Wie soll ich die Zeitstempel in der Datenbank speichern?
  2. Wie soll ich sie in der Benutzeroberfläche präsentieren?

Wenn John das Ereignis durchsucht, weiß er, dass es um 9:00 Uhr passiert ist, aber was sollte er in den Webbrowser eingeben? Er wird nichts finden, wenn er nur "9:00" als Zeitstempel eingibt, da dies möglicherweise Zürich- oder New Yorker Zeit ist (da das Ereignis nicht gefunden wurde, kann die App nicht wissen, dass es in Sidney passiert ist es kann nicht automatisch die richtige Zeitzone auswählen).

Was ist eine gute Möglichkeit, den Benutzer nach einem Zeitstempel zu fragen, der die Zeitzone enthalten könnte?

Das zweite Problem ist die Anzeige der Ergebnisse. Wenn Teams aus der ganzen Welt das Ereignis diskutieren müssen (und verwandte Ereignisse finden müssen, denken Sie an einen Cracker-Angriff, der mehrere Standorte auf der ganzen Welt gleichzeitig angreift).

Was ist ein gutes Beispiel für die Anzeige von Zeitstempeln, die möglicherweise in einer anderen Zeitzone erstellt wurden?

Hinweis: Bitte konzentrieren Sie sich auf die Verwendbarkeit der Anforderung. Ich kann die Datenbankzuordnung selbst herausfinden. Derzeit bin ich mir über den Arbeitsablauf nicht sicher. Es sollte die notwendigen Informationen auf nicht aufdringliche / intuitive Weise erfragen / präsentieren. Wenn Sie können, geben Sie einen Link zu einer vorhandenen Web-App an, die dies bereits löst.

Aaron Digulla
quelle
5
Stack Overflow löst dieses Problem, indem alles in UTC abgelegt wird. Nicht immer praktisch, aber definitiv eindeutig, nicht schwer zu implementieren und funktioniert.
Ry-
2
UTC ist verlockend, aber OTOH, SO muss Ereignisse niemals über mehrere Zeitzonen hinweg synchronisieren.
Aaron Digulla
3
Was ist, wenn eines der beteiligten Länder Gesetze erlässt, die die Ortszeit nach der geplanten Veranstaltung, jedoch vor der Veranstaltung, ändern? Wie soll das System damit umgehen? en.wikipedia.org/wiki/…
Julius Musseau
1
Diese Art der klassischen Zeitzonenfrage ist seit Jahrzehnten im Internet und in gedruckter Form so zu Tode geprügelt, dass ich überrascht bin, so lebhafte Beiträge und Prämien zu dieser Frage zu sehen!
BenSwayne
2
Meine ich nämlich einen zusätzlichen Punkt der Komplexität durch den Hinweis auf die offensichtliche, dass die meisten der westlichen Welt zweimal Zeitzonen ein Jahr ändert ( „Sommerzeit“), und dass die Regeln für die, wenn dies der Fall ist weder einheitlich global noch unbedingt trivial, algorithmisch gesprochen?
13.

Antworten:

98

Das Speichern von Zeitstempeln ist einfach: Speichern Sie sie in UTC.

Für die Anzeige ist es sinnvoll, die Zeitzoneneinstellung des Geräts als aktuelle Zeitzone zu verwenden. Das heißt, es sollte eine Zeitzonen-Dropdown-Liste neben dem Feld "Zeiteingabe" geben, die standardmäßig die aktuelle Zeitzone des Geräts verwendet, damit der Benutzer sie bei Bedarf ändern kann.

Die Mehrheit Ihrer Benutzer wird wahrscheinlich die Zeitzonen nicht viel oder überhaupt nicht ändern. Die von Ihnen beschriebene Situation ist größtenteils ungewöhnlich. Wenn Sie ein Dropdown-Menü mit einer geeigneten Standardeinstellung implementieren, sollten Sie in der Lage sein, die Dinge für diejenigen, die sich bewegen, einfach genug zu gestalten (da sie in der Regel Zeitzonen besser verstehen als Nicht-Reisende).

In der Tat wäre es sogar noch besser, die Zeitzone zu speichern, auf die das Gerät beim ersten Ausführen Ihrer App eingestellt war, und dann zu prüfen, ob sie sich jemals ändert. Wenn sich dies ändert, ist der Benutzer wahrscheinlich ein Reisender und würde wahrscheinlich von der Dropdown-Liste für die Zeitzone profitieren. Andernfalls wird nur die Dropdown-Liste und die Standardeinstellung für die Gerätezeitzone nicht angezeigt (da der Benutzer nichts darüber wissen muss). In beiden Fällen müssen Sie in der App eine Einstellung festlegen, mit der der Benutzer die Dropdown-Liste für die Zeitzone manuell ein- und ausblenden kann.


Um das Obige zusammenzufassen:

  • Speichern Sie beim ersten Start, auf welche Zeitzone das Gerät eingestellt ist.
  • Verwenden Sie diese Zeitzone als Standardzeitzone. Nehmen Sie immer diese Zeitzone an.
  • Wenn das Gerät die Zeitzone wechselt, fügen Sie eine Dropdown-Liste hinzu, um auszuwählen, in welcher Zeitzone sich das Ereignis befindet. Standardmäßig wird die Zeitzone des Geräts verwendet.
  • Fügen Sie eine Option hinzu, um diese Zeitzonen-Dropdown-Liste manuell anzuzeigen / auszublenden.
  • Speichern Sie Zeitstempel immer in UTC.
Niet the Dark Absol
quelle
Was meinen wir mit "Zeitzone"? Es scheint mehrdeutig verwendet zu werden. Dies sieht aus wie eine Referenz: en.wikipedia.org/wiki/Tz_database Was ich als "Zeitzone" bezeichnen kann, ist "Gebiet / Ort", z. B. "Amerika / New_York". Das scheint geografisch zu sein, was großartig ist, weil zum Beispiel America / Los_Angeles sowohl PST als auch PDT bedeutet, je nachdem, ob der Globus in der Sommerzeit arbeitet. Und wenn dies der Fall ist, stellt sich die Frage, wie wir die halbjährlichen Änderungen des UTC-Versatzes für die Zonen berücksichtigen. Wie nennen wir diese Wertschätzungen auch, da sie geografisch nicht "Zonen" sind?
iJames
Dies ist eine großartige Antwort. Gibt es eine bewährte Methode zum Speichern der Zeitzoneninformationen? Zum Beispiel - welches wäre besser - "PST" oder "Amerika / Pazifik"? Wie kann ich einen Zeitstempel in UTC problemlos in die erfasste Benutzerzeitzone konvertieren? Best Practices hierzu sind willkommen.
Patthebug
27

In unseren Anwendungen speichern wir im Allgemeinen die Zeitzone des Benutzers, wenn wir uns zum ersten Mal registrieren, wie dies häufig auf Forenseiten der Fall ist, und zeigen die Zeit immer mit der Zeitzone an .

Für die Speicherung der Daten ist UTC der richtige Weg. In UTC konvertieren und in die Datenbank einfügen. Konvertieren Sie beim Abrufen einfach die Zeit in die für den Benutzer festgelegte Zeitzone.

Ich musste einen ähnlichen Anwendungsfall lösen, bei dem benutzerdefinierte Benachrichtigungen wie "Happy New Year" an alle Benutzer der Web-App gesendet werden konnten. Da die Benutzer weltweit verteilt sind, mussten wir die Benachrichtigung entsprechend der Zeitzone anzeigen. Das Speichern des Zeitstempels in UTC hat unseren Zweck ohne Probleme erfüllt.

Wenn Sie in Ihrem Anwendungsfall die Benutzerzeitzone nicht irgendwo speichern, können Sie Ihre Suchergebnisse niemals genau zurückgeben, ohne nach Benutzereingaben zu fragen, es sei denn, Sie verwenden eine Art Standorterkennung wie bei gmaps, aber das ist nicht der Fall. t zuverlässig. Sie müssen also jedes Mal nach der Zeitzone fragen, um sicherzustellen, dass der Benutzer weiß, was er auf der Website eingibt.

Wenn Sie Zeitzoneninformationen haben, sollte die gesamte Web-App mit der Zeitzoneneinstellung ausgeführt werden. Wenn der Benutzer nach 9:00 sucht, sucht er daher mit der Zeitzone von Sydney. Wenn er andererseits in New York ein Ereignis erstellt, erstellt er ein Ereignis mit der Zeitzone von Sydney. Wir lösen solche Fälle, indem wir immer die Zeitzone anzeigen, während die Daten angezeigt werden.

Ich hoffe es hilft! :) :)

Varun Achar
quelle
Ich denke, mit der Hinzufügung eines Dropdowns für Zeitzonen beim Suchen und Erstellen von Ereignissen ist dies der richtige Weg. (Wenn ich nach dem Ereignis suchen muss, das von einem Kollegen in New York erstellt wurde, möchte ich nicht selbst
rechnen
Dies ist eine großartige Antwort. Gibt es eine bewährte Methode zum Speichern der Zeitzoneninformationen? Zum Beispiel - welches wäre besser - "PST" oder "Amerika / Pazifik"? Wie kann ich einen Zeitstempel in UTC problemlos in die erfasste Benutzerzeitzone konvertieren? Best Practices hierzu sind willkommen.
Patthebug
11
  1. KOORDINIERTE WELTZEIT. Halte es einfach.

  2. Verwenden Sie die Zeitzone, die für den Benutzer am relevantesten ist.

    Wenn Sie wissen, dass der Benutzer für die Veranstaltung in Sydney sein oder nach Sydney reisen wird , wird er bei der Organisation des Transports zur Veranstaltung in dieser Zeitzone nachdenken . Die Tatsache, dass sie derzeit in New York sind, ist weitgehend irrelevant. Und wenn Ihre App Datumsangaben in verschiedenen Zeitzonen anzeigt, sollte sie natürlich immer die Zeitzone neben dem Datum anzeigen , z . B. 09:00 EST .

    Wenn Ihre Benutzeroberfläche nicht zu überladen ist, können Sie Datumsangaben in der Ereigniszeitzone und in der lokalen Zeitzone anzeigen, z. B. 2012-06-13 09:00 EST (2012-06-12 19:00 EDT) .

    Ich würde argumentieren, dass die Suche ein ähnliches Problem ist, mit einer Einschränkung: Wir können falsch positive Ergebnisse tolerieren (ein Ergebnis erzielen, das wir nicht erwartet hatten), aber wir können falsch negative Ergebnisse nicht ertragen (kein Ergebnis erhalten, das wir erwartet hatten).

    Auch hier würde ich mich darauf konzentrieren, die relevanteste Zeitzone für den Benutzer zu suchen (z. B. Ereigniszeitzone) und diesen Ergebnissen in den Suchergebnissen Priorität einzuräumen. Sie können jedoch auch Ereignisse zurückgeben, die in anderen für den Benutzer relevanten Zeitzonen übereinstimmen (z Ortszeit). Wenn Sie dies tun, sollten Sie das Ereignisdatum in der übereinstimmenden Zeitzone anzeigen, insbesondere wenn Sie übereinstimmenden Text markieren.

Richard Poole
quelle
7

Hier gebe ich Vorschläge für die beste Benutzerfreundlichkeit, ohne mich um die Durchführbarkeit der Implementierung zu kümmern.
1. Für die erste Ausgabe des Speicherns von Ereignissen in db würde jeder zustimmen, sie in UTC zu speichern.

2. Um die beste Benutzererfahrung zu erzielen, speichern Sie den Verlauf der Zeitzone des Benutzers. Wenn Sie den Zeitstempel der Zeitzonenänderung speichern könnten, noch besser. Auf diese Weise können wir dem Benutzer die Freiheit geben, Abfragen durchzuführen, ohne jedes Mal die Zeitzone explizit anzugeben.

Lassen Sie uns also mit diesen Funktionen sehen, wie Suchanfragen von nur "9.00" von John behandelt werden:
Mit den oben genannten Funktionen weiß ich jetzt, dass John bis zum Datum in 2 Zeitzonen war (oder die Liste der Zeitzonen für den genannten Zeitraum abruft). Also werde ich 9.00 von Sydney Zeitzone nach UTC verdecken, eine Abfrage auslösen. Konvertieren Sie auch 9.00 von der NewYork-Zeitzone in UTC und lösen Sie eine Abfrage aus. Im Ergebnis zeige ich John 2 Zeilen, in denen er zeigt, was er um 9.00 Uhr in Sydney und um 9.00 Uhr in New York getan hat. Die Zeile in New York ist in diesem Fall leer, aber ich denke, sie sollte dem Benutzer trotzdem angezeigt werden, um ihn darüber zu informieren, dass wir auch nach dieser Zeitzone gesucht haben.

3.Was ist eine gute Möglichkeit, den Benutzer nach einem Zeitstempel zu fragen, der die Zeitzone enthalten könnte?

Wenn seine Zeitzone kürzlich geändert wurde, sollte bei jeder Anmeldung bei der Anwendung eine Benachrichtigung erfolgen, dass Ihre Standardzeitzone in die native Zeitzone geändert wird.
Angenommen, der Benutzer wählt beim Erstellen eines Ereignisses die Zeitzone aus der Dropdown-Liste aus. Belasten Sie den Benutzer nicht, indem Sie Optionen für alle Zeitzonen der Welt angeben. Die erste Dropdown-Option sollte die aktuelle Zeitzone des Geräts des Benutzers sein. danach Zeitzonen aus seiner Geschichte der Zeitzonen, dann UTC und dann verbleibende Zeitzonen, die er bis heute nie benutzt hat.

4.Wie werden die Ergebnisse angezeigt, wenn Teams aus aller Welt das Ereignis diskutieren müssen:

Ich möchte diesen Anwendungsfall auf die Anzahl der Teams 2 oder mehr als 2 aufteilen.
Für nur 2 Teams würde ich es vorziehen, wenn jedes Team den Zeitstempel in seiner lokalen Zeitzone und in der Zeitzone des anderen Teams sieht. (Ich persönlich bevorzuge es, in der Zeitzone der Person am anderen Ende zu sprechen, um ein Meeting zu planen.) Für mehr als 2 Teams ist es besser, eine häufigere Zeitzone zu berücksichtigen, z. B. UTC. In diesem Fall sollte jeder Benutzer den Zeitstempel in zwei Zeitzonen, in UTC und in seiner Standardzeitzone sehen.

Diese Vorschläge werden mit der Absicht gemacht, dass der Benutzer in seiner Ortszeit keine Berechnung durchführen muss, gleichzeitig aber in der Lage sein sollte, mit anderen Benutzern in ihrer bevorzugten Zeitzone fließend zu kommunizieren.

Pranalee
quelle
2
+1 Dies ist eine sehr interessante Idee, da ich weiß, dass der Benutzer um 9:00 Uhr in Sidney ein Ereignis eingegeben hat. Wenn derselbe Benutzer nach einer Zeit sucht (ohne explizite Zeitzone), sollte ich davon ausgehen, dass er "wo ich war" bedeutet dieses Mal "
Aaron Digulla
4

Ok, ich habe einen anderen Ansatz als andere:

Erstens habe ich einige Dinge vorher angenommen.

Die Person, die ein Ereignis auflistet, hat ein Smartphone (wenn es sich um einen Browser handelt, muss ich diese Annahmen nicht treffen) mit:

  1. GPS

  2. HTML5-Fähigkeit.

  3. Javascript-Fähigkeit

Wie soll ich die Zeitstempel in der Datenbank speichern?

Lösung: Offensichtlich UTC habe ich das folgende Verfahren überlagert:

Schritt 1. Verwenden Sie die Geolocation des Benutzers mithilfe der Geolocation-API

    window.onload = getMyLocation;

    function getMyLocation() {
        if (navigator.geolocation) {
            navigator.geolocation.getCurrentPosition(displayLocation);
        } else {
            alert("Oops, no geolocation support");
        }
    }

    function displayLocation(position) {
        var latitude = position.coords.latitude;
        var longitude = position.coords.longitude;
        var div = document.getElementById("location");
        div.innerHTML = "You are at Latitude: " + latitude + ", Longitude: " + longitude;
    }

Schritt 2. Geben Sie das (Long, Lat) als Argument für einige der (Lat, Long) zu TimeZone- APIs wie der Yahoo-API (verwenden Sie Flag R, um das Latitude in die Zeitzone zu konvertieren), um die Zeitzone des Benutzers abzurufen.

=> Die Zeitzone des Benutzers wird ohne Benutzereingabe bestimmt (ich verwende dies, weil Sie nicht einfach davon ausgehen können, dass der Benutzer die Zeitzone des Ortes kennt, in dem er lebt. Ich kannte meine Zeitzone erst nach wenigen Monaten oder etwas am Ort: P, ziemlich dumm! )

Die jede Ereignistabelle hat Timezoneund Eventkann auch CityName eine andere Datenbanktabelle mit Klassifizierung basierend auf CityNames erstellen . Hier hat der Benutzer also zwei Spalten

|---------------------------------------|
|_____NewYork________|______Sydney______|
|                    |                  |
|Event 1             |  Event 2         |
|____________________|__________________| 

Für die Benutzeroberfläche

=> Verwenden Sie die Google Kalender-API oder einige der Kalender-APIs

Verwandte Lesungen:

  1. Bestimmen Sie die Zeitzone aus Längen- und Breitengraden, ohne Webdienste wie Geonames.org zu verwenden

  2. Zeitzonensuche vom Längen- und Breitengrad

Ich weiß, es geht nur darum, eine Idee zu zeigen, wie man dieses Problem löst. Sehen Sie jedoch, wie genau und leicht es für Benutzer wird, wenn die Zeitzone mithilfe von Geräte-APIs bestimmt wird

Ich hoffe es hilft!

uday
quelle
4
Es ist ziemlich einfach, die Zeitzone einer Person ohne Geolokalisierung zu finden. new Date().getTimezoneOffset()gibt es in Minuten hinter UTC.
Ry-
@minitech, das stimmt, aber was ist, wenn das Ereignis in New York und irgendwo im Süden stattfindet, wo es dieselbe Zeitzone gibt? Ich verwende Geolocation, damit Sie die Stadt (sogar genau), die Zeitzone in einem Schuss genau bestimmen und meine Datenbank-Tabelle darauf aufbauen können. Ich möchte Benutzereingaben mithilfe der Geräte-API minimieren , um die Effektivität der App zu erhöhen.
uday
So? Die Zeit wird an beiden Orten gleich sein, es gibt also kein Problem. -1
Ry-
@minitech, Sie können diesen Link sehen, warum ich die Verwendung von Geräte-APIs als andere Methoden empfehle . webdirections.org/sotmw2011
uday
2
Okay, aber hier geht es nicht darum, die Stadt des Benutzers zu ermitteln. Es geht nur darum, die Zeitzone zu bekommen. Die Verwendung einer Geolocation-API, die nicht auf jedem Browser / Computer funktioniert, und die Umleitung zu einer Kalender-API ist eine schlechte Methode, um die Zeitzone eines Benutzers abzurufen, wenn sie in einer Codezeile verfügbar ist.
Ry-
2

Für diesen speziellen Fall würde ich sowohl lokale als auch UTC-Zeit speichern . UTC ist etwas wichtig und wird für die Synchronisierung und Konvertierung der Zeit in die aktuelle Zeitzone verwendet. Local wird für Suchvorgänge und zusätzliche Informationen verwendet, z.

Sie haben ein Treffen:

12:00 Monday (UTC)
9:00 Monday (Sydney, creation local time)
11:00 Monday (Zurich, local time)

oder etwas ähnliches. Die andere Möglichkeit besteht darin, die Erstellungszeitzone zu speichern und zur Laufzeit zu konvertieren (dies ist besonders dann besser, wenn der Benutzer die Besprechungszeit ändert). In beiden Fällen besteht der Hauptgrund darin, dass die ursprüngliche Erstellungszeit wiederhergestellt werden kann, damit der Benutzer darauf verweisen kann.

Petr Abdulin
quelle
2
  1. Wie soll ich die Zeitstempel in der Datenbank speichern?

Bei der Ereigniserstellung würde ich die UTC-Zeit und die lokale Zeitzone (auch bekannt als creation time zone) speichern . Ich würde das, was ich gespeichert habe, verwenden, um die UTC-Zeit in Ortszeit (auch bekannt als creation time) umzuwandeln und sie neben der UTC-Zeit und zu speichern creation time zone.

HINWEIS: Ich kann die Ortszeit von Anfang an speichern, aber wenn der Benutzer nach einem Ereignis sucht, würde ich hoffen, dass eine Konvertierung in die Ortszeit vorliegt. Ich hoffe auch, dass der Server erkennen kann, in welcher Zeitzone sich der Client befindet.

  1. Wie soll ich sie in der Benutzeroberfläche präsentieren?

Wenn ein Benutzer nach "9:00" sucht, würde ich nach Ereignissen suchen, die "9:00" entweder in UTC ODER creation time ODER Ortszeit enthalten. Für die Ergebnisse würde ich eine Ergebnistabelle in anzeigen creation time(Dies soll Zeitstempel anzeigen, die möglicherweise in einer anderen Zeitzone erstellt wurden, da wir davon ausgehen, dass der Benutzer nach der Zeit sucht, zu der er ein Ereignis erstellt hat, wo immer er war.) und zeigen Sie unten eine zweite Ergebnistabelle mit verwandten Ergebnissen an, möglicherweise mit der Überschrift "Nicht das, wonach Sie suchen? Siehe verwandte Ergebnisse" (dazu gehören die verbleibenden UTC- und Ortszeitergebnisse).

Insgesamt würde ich die UTC-Zeit, die Ortszeit, die creation timeund creation time zone(dh die Ortszeit und die Zeitzone des Ereignisses, in dem es erstellt wurde) sortiert nach UTC-Zeit anzeigen , damit Sie sehen können, welches Ereignis zuerst eintritt, falls zwei unterschiedliche Ereignisse vorliegen Die Veranstaltungen waren für 9:00 Uhr in zwei verschiedenen Zeitzonen geplant.


quelle
1
+1 Ich mag die Idee, alle Ereignisse in allen Zeitzonen anzuzeigen, in denen die Ortszeit übereinstimmt. Ich bin nur unzufrieden mit SQL (24x BETWEENBedingungen).
Aaron Digulla