Come posso gestire i fusi orari nella mia webapp?


106

Sto cercando una migliore comprensione della seguente storia utente:

John lavora a Sidney. Alle 9:00 del mattino, registra un evento in un'app Web che viene eseguita su un server a Zurigo. Il giorno successivo, si reca a New York per una riunione di emergenza in cui si dovrebbe discutere l'evento. Durante la riunione, cerca l'evento per data e ora.

A mio modo di vedere, ci sono almeno due problemi qui:

  1. Come devo salvare i timestamp nel database
  2. Come dovrei presentarli nell'interfaccia utente

Quando John cerca l'evento, saprà che è successo alle 9:00 ma cosa deve inserire nel browser web? Non troverà nulla quando inserirà "9:00" come timestamp perché potrebbe essere l'ora di Zurigo o di New York (poiché l'evento non è stato trovato, l'app non ha modo di sapere che è successo a Sidney, quindi non può selezionare automaticamente il fuso orario corretto).

Qual è un buon modo per chiedere all'utente un timestamp che potrebbe includere il fuso orario?

Il secondo problema è come visualizzare i risultati. Se i team di tutto il mondo hanno bisogno di discutere dell'evento (e trovare eventi correlati, pensa a un attacco di cracker che prende di mira diversi siti in tutto il mondo contemporaneamente).

Qual è un buon esempio per la visualizzazione di timestamp che potrebbero essere stati creati in un fuso orario diverso?

Nota: concentrarsi sull'usabilità del requisito. Posso capire da solo la mappatura del database. Al momento non sono sicuro del flusso di lavoro. Dovrebbe chiedere / presentare le informazioni necessarie in modo non intrusivo / intuitivo. Se puoi, dai un collegamento a un'app Web esistente che già risolve il problema.


5
Stack Overflow risolve questo problema mettendo tutto in UTC. Non sempre conveniente, ma è decisamente univoco, non difficile da implementare e funziona.
Ry-

2
L'UTC è allettante, ma OTOH, SO non ha mai bisogno di sincronizzare gli eventi su più fusi orari.
Aaron Digulla

3
Cosa succede se uno dei paesi coinvolti emana una legislazione che cambia l'ora locale dopo che l'evento è stato programmato, ma prima che si verifichi l'evento? Come dovrebbe gestirlo il sistema? en.wikipedia.org/wiki/…
Julius Musseau,

1
Questo tipo di classica domanda sul fuso orario è stata così picchiata a morte per decenni su Internet e sulla stampa, sono sorpreso di vedere un input così vivace e taglie su questa domanda!
BenSwayne

2
Aggiungo un ulteriore punto di complessità sottolineando l'ovvio, vale a dire che la maggior parte del mondo occidentale cambia i fusi orari due volte l'anno ("ora legale"), e che le regole per quando ciò si verifica non sono né uniformi a livello globale né necessariamente banali, algoritmicamente parlando?
13

Risposte:


99

Il problema della memorizzazione dei timestamp è semplice: memorizzali in UTC.

Per quanto riguarda la visualizzazione, avrebbe senso prendere l'impostazione del fuso orario del dispositivo e utilizzarla come fuso orario corrente. Detto questo, dovrebbe esserci un menu a discesa del fuso orario accanto alla casella "input dell'ora", che per impostazione predefinita è il fuso orario corrente del dispositivo, in modo che l'utente possa modificarlo se necessario.

La maggior parte dei tuoi utenti probabilmente non cambierà molto o per niente i fusi orari. Per la maggior parte, la situazione che hai delineato è rara. Implementando un menu a discesa con un'impostazione predefinita adeguata, dovresti essere in grado di rendere le cose abbastanza facili per coloro che si spostano (perché in genere hanno una migliore comprensione dei fusi orari rispetto a un non viaggiatore).

In effetti, sarebbe ancora meglio salvare il fuso orario su cui era impostato il dispositivo quando la tua app è stata eseguita per la prima volta, e poi vedere se cambia mai. Se cambia, l'utente è probabilmente un viaggiatore e probabilmente trarrebbe vantaggio dall'avere il menu a discesa del fuso orario. Altrimenti, non mostrare il menu a discesa e l'impostazione predefinita per il fuso orario del dispositivo (perché l'utente non ha bisogno di conoscerli). In entrambi i casi, avere un'impostazione nell'app che consenta all'utente di mostrare / nascondere manualmente il menu a discesa del fuso orario.


Per riassumere quanto sopra:

  • Alla prima esecuzione, salva il fuso orario su cui è impostato il dispositivo.
  • Usa quel fuso orario come fuso orario predefinito. Assumi sempre quel fuso orario.
  • Se il dispositivo cambia fuso orario, aggiungere un menu a discesa per selezionare il fuso orario in cui si trova l'evento, impostando per impostazione predefinita il fuso orario del dispositivo.
  • Aggiungi un'opzione per mostrare / nascondere manualmente questo menu a discesa del fuso orario.
  • Memorizza sempre i timestamp in UTC.

Cosa si intende per "fuso orario" Sembra usato in modo ambiguo. Questo sembra un riferimento: en.wikipedia.org/wiki/Tz_database Da quello che posso dire un "fuso orario" è "Area / Località", ad esempio "America / New_York". Sembra essere geografico, il che è fantastico perché ad esempio America / Los_Angeles significa SIA PST che PDT a seconda che il globo funzioni nell'ora legale. E se è così, la domanda è: come si tengono conto delle variazioni biennali dell'offset UTC per le zone? Inoltre come chiamiamo queste abbreviazioni dal momento che non sono "zone" geograficamente giuste?
iJames

Questa è un'ottima risposta. Esiste una best practice su come memorizzare le informazioni sul fuso orario? Ad esempio, quale sarebbe meglio, "PST" o "America / Pacifico"? Come potrò convertire facilmente un timestamp in UTC nel fuso orario dell'utente acquisito? Eventuali migliori pratiche su questo sarebbero apprezzate.
Patthebug

27

Nelle nostre applicazioni, generalmente memorizziamo il fuso orario dell'utente quando ci registriamo per la prima volta, come spesso si vede sui siti del forum, e visualizziamo sempre l'ora con il fuso orario .

Per quanto riguarda la memorizzazione delle date, UTC è la strada da percorrere. Converti in UTC e inseriscilo nel database. Durante il recupero, converti semplicemente l'ora nel fuso orario impostato per l'utente.

Ho dovuto risolvere un caso d'uso simile, in cui le notifiche personalizzate, come "Happy New Year", potevano essere inviate a tutti gli utenti dell'applicazione web. Poiché gli utenti sono distribuiti in tutto il mondo, era necessario visualizzare la notifica in base al fuso orario. La memorizzazione del timestamp in UTC è stata utile al nostro scopo, senza intoppi.

Nel tuo caso d'uso, se non stai memorizzando il fuso orario dell'utente da qualche parte non sarai mai in grado di restituire con precisione i risultati della ricerca senza chiedere l'input dell'utente, a meno che tu non inizi a utilizzare una sorta di rilevamento della posizione come fa gmaps, ma non è così t affidabile. Quindi dovrai chiedere ogni volta il fuso orario per assicurarti che l'utente sappia cosa sta inserendo nel sito web.

Se disponi di informazioni sul fuso orario, l'intera app web dovrebbe essere eseguita con l'impostazione del fuso orario. Quindi, quando l'utente cerca le 9:00, cercherà con il fuso orario di Sydney. D'altra parte, se crea un evento mentre è seduto a New York, creerà un evento con il fuso orario di Sydney. Risolviamo questi casi visualizzando sempre il fuso orario durante la visualizzazione delle date.

Spero che sia d'aiuto! :)


Penso che con l'aggiunta di un menu a discesa per i fusi orari durante la ricerca e la creazione di eventi, questa sia la strada da percorrere. (quando devo cercare l'evento creato dal collega a New York, non voglio fare i
conti da

Questa è un'ottima risposta. Esiste una best practice su come memorizzare le informazioni sul fuso orario? Ad esempio, quale sarebbe meglio, "PST" o "America / Pacifico"? Come potrò convertire facilmente un timestamp in UTC nel fuso orario dell'utente acquisito? Eventuali migliori pratiche su questo sarebbero apprezzate.
Patthebug

11
  1. UTC. Sii semplice.

  2. Utilizza il fuso orario più rilevante per l'utente.

    Se sai che l'utente si troverà o viaggerà a Sydney per l'evento, allora penserà a quel fuso orario quando organizza il trasporto per l'evento. Il fatto che siano attualmente a New York è in gran parte irrilevante. E, naturalmente, se la tua app mostra le date in una varietà di fusi orari, dovrebbe sempre mostrare il fuso orario accanto alla data, ad esempio 09:00 EST .

    Se non confonde troppo la tua interfaccia, potresti visualizzare le date nel fuso orario dell'evento e nel fuso orario locale, ad esempio 2012-06-13 09:00 EST (2012-06-12 19:00 EDT) .

    Direi che la ricerca è un problema simile, con un avvertimento: possiamo tollerare i falsi positivi (ottenendo un risultato che non ci aspettavamo), ma non possiamo sopportare i falsi negativi (non ottenendo un risultato che ci aspettavamo).

    Ancora una volta, mi concentrerei sulla ricerca del fuso orario più pertinente per l'utente (ad es. Fuso orario dell'evento) e darebbe priorità a questi risultati nei risultati di ricerca, ma puoi anche restituire eventi che corrispondono in altri fusi orari rilevanti per l'utente (ad es. ora locale). Se lo fai, dovresti mostrare la data dell'evento nel fuso orario corrispondente, soprattutto se evidenzi il testo corrispondente.


7

Qui sto dando suggerimenti per la migliore usabilità senza preoccuparmi troppo della fattibilità dell'implementazione.
1. Per il primo numero di archiviazione degli eventi in db, tutti accetterebbero di memorizzarli in UTC

2. Per offrire la migliore esperienza utente, salvare la cronologia del fuso orario dell'utente. Se potessi salvare il timestamp del cambio di fuso orario, ancora meglio. Questo ci consentirà di dare libertà all'utente di interrogare senza specificare esplicitamente il fuso orario ogni volta.

Quindi, con queste funzionalità, vediamo come verrà gestita la query di ricerca di solo "9.00" di John:
Con le funzionalità sopra menzionate, ora so che John è stato in 2 fusi orari fino alla data (o ottieni l'elenco dei fusi orari per il periodo menzionato). Quindi coprirò le 9.00 dal fuso orario di Sydney a UTC, e avvierò una query. Converti anche le 9.00 del fuso orario di NewYork in UTC, avvia una query. Di conseguenza mostrerò 2 righe a John che mostra ciò che ha fatto alle 9.00 a Sydney e alle 9.00 a New York. La riga di New York sarà vuota in questo caso, ma penso che dovrebbe comunque essere mostrata all'utente, solo per informarlo che abbiamo cercato anche questo fuso orario.

3.Qual è un buon modo per chiedere all'utente un timestamp che potrebbe includere il fuso orario?

Se il suo fuso orario è stato modificato di recente, ogni volta che accede all'applicazione, dovrebbe essere data una notifica che il fuso orario predefinito viene modificato in fuso orario nativo.
Durante la creazione dell'evento, diciamo che l'utente seleziona il fuso orario dal menu a discesa.Non sovraccaricare l'utente fornendo le opzioni di tutti i fusi orari del mondo.La prima opzione del menu a discesa dovrebbe essere il fuso orario corrente del dispositivo dell'utente. dopo di che fusi orari dalla sua cronologia dei fusi orari, poi UTC e poi fusi orari rimanenti che non ha mai utilizzato fino ad oggi.

4.Come visualizzare i risultati, se le squadre di tutto il mondo hanno bisogno di discutere dell'evento:

Vorrei dividere questo caso d'uso tra il numero di squadre 2 o più di 2.
Per solo 2 squadre, preferirei che ogni squadra visualizzi il timestamp nel proprio fuso orario locale e nel fuso orario dell'altra squadra. (Personalmente preferisco parlare nel fuso orario della persona dall'altra parte per sua comodità durante la pianificazione di una riunione). Per più di 2 squadre, è meglio considerare un fuso orario più comune, ad esempio UTC. Quindi, in questo caso, ogni utente dovrebbe vedere il timestamp in 2 fusi orari, in UTC e nel suo fuso orario predefinito.

Questi suggerimenti sono forniti con l'intenzione che l'utente non debba eseguire alcun calcolo nella sua ora locale, ma allo stesso tempo dovrebbe essere in grado di comunicare con altri utenti fluentemente nel loro fuso orario preferito.


2
+1 Questa è un'idea molto interessante perché so che l'utente ha inserito un evento alle 9:00 a Sidney, quindi quando lo stesso utente cerca un'ora (senza fuso orario esplicito), dovrei presumere che significhi "dove mi trovavo quella volta "
Aaron Digulla

4

Ok ho un approccio diverso dagli altri:

In primo luogo, ho ipotizzato poche cose prima.

La persona che sta elencando un evento ha uno smartphone (se è un browser, non devo fare queste ipotesi) con:

  1. GPS

  2. Capacità HTML5.

  3. Funzionalità Javascript

Come devo salvare i timestamp nel database?

Soluzione: ovviamente UTC , ho sovrapposto la procedura di seguito:

Passaggio 1. Utilizza la geolocalizzazione dell'utente utilizzando l'API di geolocalizzazione

    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;
    }

Passaggio 2. Fornisci le (Long, Lat) come argomentazioni ad alcune delle (Lat, Long) api TimeZone come le API di Yahoo (utilizzare Flag R per convertire la Latitude in Timezone) per ottenere il fuso orario degli utenti.

=> Il fuso orario dell'utente è determinato senza l'input dell'utente (lo sto usando perché non si può semplicemente presumere che l'utente conosca il fuso orario del luogo in cui vive, conoscevo il mio fuso orario solo dopo pochi mesi o qualcosa del genere: P, abbastanza stupido! )

Ogni tabella di eventi ha Timezone, Evente quindi può anche avere CityName Quindi creare un'altra tabella di database con classificazione basata su CityNames. Quindi qui l'utente avrà due colonne

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

Per l'interfaccia utente

=> usa l'API di Google Calendar o alcune delle API di Calendar

Letture correlate:

  1. Determina il fuso orario da latitudine / longitudine senza utilizzare servizi web come Geonames.org

  2. Ricerca del fuso orario dalla latitudine longitudine

So che si tratta solo di mostrare qualche idea su come risolvere questo problema. Ma guarda quanto diventa accurato e leggero per gli utenti quando il fuso orario viene determinato utilizzando le API del dispositivo

Spero che sia d'aiuto!


4
È abbastanza facile trovare il fuso orario di qualcuno senza geolocalizzazione. new Date().getTimezoneOffset()lo dà in pochi minuti rispetto a UTC.
Ry-

@minitech, questo è vero, ma cosa succede se l'evento sta accadendo a NewYork e da qualche parte a sud, dove ha lo stesso fuso orario. Sto usando la geolocalizzazione in modo che tu possa individuare la città (anche accurata), il fuso orario in uno scatto e basare la mia tabella db su di esso. Voglio ridurre al minimo l'input dell'utente utilizzando l' API del dispositivo per aumentare l'efficacia dell'app.
uday

Così? L'orario sarà lo stesso in entrambi i posti, quindi non c'è problema. -1
Ry-

@minitech, puoi vedere questo link sul motivo per cui consiglio di utilizzare le API del dispositivo rispetto ad altri metodi. webdirections.org/sotmw2011
uday

2
Va bene, ma il problema qui non è ottenere la città dell'utente. Si tratta solo di ottenere il fuso orario. Utilizzare un'API di geolocalizzazione che non funziona su tutti i browser / computer, quindi reindirizzare a un'API di calendario, è un cattivo modo per ottenere il fuso orario di un utente quando è disponibile in una riga di codice.
Ry-

2

Per quel caso particolare, memorizzerei sia l'ora locale che quella UTC. L'UTC è un po 'importante e viene utilizzato per la sincronizzazione e la conversione dell'ora nel fuso orario corrente. Locale viene utilizzato per le ricerche e per ulteriori informazioni, come:

Hai un incontro:

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

o qualcosa di simile. L'altro modo è memorizzare il fuso orario di creazione e convertire in fase di esecuzione (questo è particolarmente meglio nel caso in cui l'utente cambierà l'orario della riunione). In entrambi i casi, il motivo principale è essere in grado di ripristinare l'ora di creazione originale in modo che l'utente possa fare riferimento ad essa.


2
  1. Come devo salvare i timestamp nel database

Alla creazione dell'evento, memorizzerei l'ora UTC e il fuso orario locale (aka creation time zone). Userei ciò che ho memorizzato per convertire l'ora UTC in ora locale (aka creation time) e memorizzarla insieme all'ora UTC e creation time zone.

NOTA: posso memorizzare l'ora locale sin dall'inizio, ma quando l'utente cerca un evento, spero che esista una conversione all'ora locale. Spero anche che il server possa rilevare in quale fuso orario si trova il client.

  1. Come dovrei presentarli nell'interfaccia utente

Quando un utente cerca "9:00", cercherò eventi che includono "9:00" in UTC OPPURE creation time O ora locale. Per i risultati, vorrei visualizzare una tabella dei risultati in creation time(Questo ha lo scopo di visualizzare i timestamp che potrebbero essere stati creati in un fuso orario diverso, poiché presumiamo che l'utente stia cercando a che ora ha creato un evento ovunque si trovasse.) e visualizza una seconda tabella di risultati di seguito con i risultati correlati, magari con l'intestazione "Non è quello che stai cercando? Visualizza i risultati correlati" (questi includono i risultati UTC e ora locale rimanenti).

Nel complesso, vorrei visualizzare l'ora UTC, l'ora locale, il creation timee creation time zone(ovvero l'ora locale e il fuso orario dell'evento in cui è stato creato) ordinati per ora UTC, in modo da poter vedere quale evento viene prima, nel caso in cui due diversi gli eventi erano previsti per le 9:00 in due fusi orari diversi.


1
+1 Mi piace l'idea di mostrare tutti gli eventi in tutti i fusi orari in cui l'ora locale corrisponde; Sono solo insoddisfatto dell'SQL ( BETWEENcondizioni 24x ).
Aaron Digulla,
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.