2013-08-08 3 views
7

Sto sviluppando un sito Web in cui devo gestire diversi possibili fusi orari dagli utenti. Questo diventa un grande problema dal momento che il sito ospita eventi delicati nel tempo come le aste.Come gestire i fusi orari tra server e client?

Tutte le date/orari sul server sono in UTC. Il database archivia tutto nei timestamp UTC. Anche il fuso orario predefinito di PHP è impostato su UTC (date_default_timezone_set('UTC');).

Ora, il mio problema è come dovrei interagire con gli utenti, se sto mostrando solo una data o, ancora più importante, sto leggendo la data/ora da input dell'utente.

Un esempio concreto:

  • ad un'asta ha una scadenza, che devo conservare nel database come UTC.
  • Quando visualizzo l'asta sul sito Web, un timer javascript utilizza un oggetto Date per calcolare il tempo rimanente. Converte automaticamente il fuso orario in GMT + 0100 (il mio fuso orario locale). Quindi se la scadenza è '2013-08-08 10:46:08' (UTC), l'oggetto data javascript restituirà Aug 08 2013 11:26:15 GMT+0100 (GMT Standard Time).
  • Se l'ora corrente è maggiore di 11:46:08, il timer indica che il tempo rimanente è 00:00 (che è corretto).
  • Ma se provo ad inserire un'offerta, il server accetta poiché la condizione sulla MySQL INSERT viene valutata a true:

    INSERT INTO offerte ... Dove ... E auction_deadline> NOW() ...

(perché auction_deadline = '2013-08-08 10:46:08' e NOW() = '2013-08-08 10:26:50')

Tutto questo mumbo Jumbo di fuso orario si scioglie il mio cervello. Cosa mi manca qui? Sono quasi sicuro che memorizzare tutte le date/orari in UTC all'interno del database sia il migliore. Non riesco a pensare in modo chiaro come gestirlo tra l'utente e il database.

+0

Se hai bisogno di un codice per chiarire la mia domanda, dillo per favore. –

risposta

3

Il tuo problema non riguarda affatto i fusi orari, solo il fatto che i clienti possano girare i propri orologi o avere un orologio molto inclinato. Per questo la correzione è di eseguire il polling del server una volta ogni tanto per una correzione dell'offset da utilizzare nei calcoli.

In effetti, non hai nemmeno bisogno di oggetti data. C'è un certo istante universale nel tempo in cui termina l'asta. Diciamo che è 1375960662823. In questo momento, l'istante temporale universale è 1375960669199, quindi da quello che vediamo l'asta termina in 6 secondi (1375960662823 - 1375960669199 ~ 6000). Finirà in 6 secondi, indipendentemente dal fatto che io sia in Marocco o in Giappone. Lo capisci ancora?

Per generare questi numeri, sul lato client è possibile chiamare var now = Date.now() + skewFix dove skewFix è la correzione che deve essere applicata nel caso in cui il client abbia l'inclinazione del tempo o il tempo impostato manualmente sul computer.

In PHP, è possibile generare con $now = time() * 1000;

0

è possibile effettuare le seguenti

volta pagina viene caricata, inviare una richiesta Ajax per server con offset del fuso orario dell'utente. È possibile ottenere lo sfasamento del fuso orario utilizzando il seguente codice.

var curdate = new Date() 
var offset = curdate.getTimezoneOffset() 

l'offset è fuso orario fuso in minuti.

Penso che sarà d'aiuto.

0

Questo è piuttosto un argomento tipico ma molto complesso da comprendere per la maggior parte. Per prima cosa, non menzioni mai il DAYLIGHT SAVING. sì, sto aumentando la tensione :).

Ora vediamo come possiamo farlo. Hai fatto un buon lavoro salvando l'ora in UTC. Ora, spero che tu abbia membri registrati e che ogni membro abbia la possibilità di impostare il proprio fuso orario preferito, altrimenti mostrerai loro il tempo basato sul fuso orario del server.

Quando si attraversa "l'ora di inizio" per l'utente, è necessario inviarli dopo aver convertito l'ora UTC al proprio orario, in modo simile quando si accetta TIME dal browser sia azione dell'utente che javascript è necessario convertire tale ora in UTC considerando il fatto che l'utente è quel fuso orario che seleziona per il suo profilo.

Spero che chiarisca l'idea su dove stai andando male? Si prega di leggere la luce del giorno risparmiando in quanto avrà un ruolo importante anche quando si passa avanti con altra logica sullo stesso.

EDIT:

È possibile utilizzare compensato Fuso orario di javascript, per la presentazione di auto e l'input dell'utente sulla base delle sue impostazioni.

0

ogni volta quando si ottiene la data dal lato client, è possibile utilizzare il getUTC per convertire in data UTC cioè:

var todayDate = new Date(); 

var todayDateInUTC = new Date(todayDate.getUTCFullYear(), todayDate.getUTCMonth(), todayDate.getUTCDate(), todayDate.getUTCHours(), todayDate.getUTCMinutes(), todayDate.getUTCSeconds()); 

modo giusto prima di inserire la data di offerta di base di dati, utilizzare le funzioni getUTC per convertire in formato UTC.

1

Data in JavaScript utilizza fuso orario locale. Si dovrebbe ottenere il tempo UTC per l'utente e la invia al server di

new Date 
Thu Aug 08 2013 17:00:14 GMT+0530 (India Standard Time) 
(new Date("Thu Aug 08 2013 17:00:14")).toUTCString(); 
"Thu, 08 Aug 2013 11:30:14 GMT" 

Questo risolverà il problema fuso orario tra il server e il client.

1

Lei ha detto

(perché auction_deadline = '2013/08/08 10:46:08' e NOW() = '2013/08/08 10:26:50')

In MySQL - NOW restituisce l'ora corrente nel fuso orario locale del server (docs).

probabilmente si desidera qualcosa di simile UTC_TIMESTAMP che restituisce l'ora corrente in UTC (docs).

Inoltre, probabilmente non si dovrebbe accettare alcun tempo di input dal client JavaScript. Fidati solo del tuo orologio. Quando viene piazzata un'offerta, usa l'ora sul tuo server in MySQL o in PHP. Non accettarlo come input.