2013-07-25 15 views
53

Perché moment.js UTC mostra sempre la data errata. Ad esempio dalla Console per gli sviluppatori di Chrome:momento.js - UTC data errata

moment(('07-18-2013')).utc().format("YYYY-MM-DD").toString() 
// or 
moment.utc(new Date('07-18-2013')).format("YYYY-MM-DD").toString() 

Entrambi torneranno "2013/07/17" Perché è tornando invece di , che è stata approvata in

. ma se io uso momentjs senza l'UTC:

moment(new Date('07-18-2013')).format("YYYY-MM-DD").toString() 

torno "2013/07/18" che è anche ciò che mi aspetto quando utilizzo moment.js UTC.

Significa che non è possibile ottenere la data corretta quando si utilizza moment.js UTC?

+1

Non penso che sia necessario 'toString()' dopo 'format()' (restituisce già una stringa). – alex

risposta

81

Per impostazione predefinita, MomentJS analizza in ora locale. Se viene fornita solo una stringa di data (senza tempo), l'ora predefinita è mezzanotte.

Nel codice, si crea una data locale e quindi la si converte nel fuso orario UTC (infatti, l'istanza dell'istanza del momento passa a UTC mode), quindi quando è formattata, viene spostata (in base all'ora locale)) avanti o indietro.

Se il fuso orario locale è UTC + N (N è un numero positivo) e si analizza una stringa di sola data, si otterrà la data precedente.

Ecco alcuni esempi per illustrare essa (la mia ora locale offset è GMT + 3 durante l'ora legale):

>>> moment('07-18-2013', 'MM-DD-YYYY').utc().format("YYYY-MM-DD HH:mm") 
"2013-07-17 21:00" 
>>> moment('07-18-2013 12:00', 'MM-DD-YYYY HH:mm').utc().format("YYYY-MM-DD HH:mm") 
"2013-07-18 09:00" 
>>> Date() 
"Thu Jul 25 2013 14:28:45 GMT+0300 (Jerusalem Daylight Time)" 

Se si desidera che la stringa data-ora interpretata come UTC, si dovrebbe essere esplicito in proposito:

>>> moment(new Date('07-18-2013 UTC')).utc().format("YYYY-MM-DD HH:mm") 
"2013-07-18 00:00" 

o, come Matt Johnson cita nella sua risposta, è possibile (e probabilmente dovrebbe) analizzare come una data UTC, in primo luogo con moment.utc() e includere la stringa di formato come secondo argomento di pre sfogo all'ambiguità.

>>> moment.utc('07-18-2013', 'MM-DD-YYYY').format("YYYY-MM-DD HH:mm") 
"2013-07-18 00:00" 

Per passare il contrario e convertire una data UTC per una data locale, è possibile utilizzare il metodo local(), come segue:

>>> moment.utc('07-18-2013', 'MM-DD-YYYY').local().format("YYYY-MM-DD HH:mm") 
"2013-07-18 03:00" 
+0

Mille grazie. Quindi, in pratica, dovrei sempre passare il tempo quando uso UTC o passare in UTC come nel tuo secondo approccio. – brg

+0

In alternativa o attenersi al fuso orario locale. Se invii orari dal server, puoi esprimerli come timestamp Unix (X) o come stringhe in un fuso orario specifico. Perché utilizzare l'UTC al posto del fuso orario locale dell'utente, ad ogni modo (tranne che per l'invio di dati normalizzati al server)? – MasterAM

+1

Ricorda che 'new Date ('07 -18-2013 UTC ')' non funzionerà in IE8, se ti interessa. –

20

Sia Date e moment sarà analizzare la stringa di input in il fuso orario locale del browser per impostazione predefinita. Tuttavia, Date a volte è incoerente con questo proposito. Se la stringa è specificatamente YYYY-MM-DD, utilizzando i trattini o se è YYYY-MM-DD HH:mm:ss, la interpreterà come ora locale. A differenza di Date, moment sarà sempre coerente sul modo in cui viene analizzato.

Il modo corretto per analizzare un momento ingresso come UTC nel formato che hai fornito sarebbe come questo:

moment.utc('07-18-2013', 'MM-DD-YYYY') 

Fare riferimento a this documentation.

Se si vuole quindi formattare in modo diverso per l'uscita, si dovrebbe fare questo:

moment.utc('07-18-2013', 'MM-DD-YYYY').format('YYYY-MM-DD') 

Non è necessario chiamare in modo esplicito toString.

Si noti che è molto importante fornire il formato di input. Senza di esso, una data come 01-04-2013 potrebbe essere elaborata come Gen 4 o 1o aprile, a seconda delle impostazioni di cultura del browser.

+0

Grazie Matt, ho messo in circolazione la tua grande risposta. – brg

+0

Solo per motivi di apprendimento, nella console: ** moment.utc ('2013-07-18 0:00 +0100', 'AAAA-MM-GG HH: mm') ** mi da ** "2013-07 -18 0:00 +0100 "** Ma quale differenza su jsfiddle quando è in esecuzione è diversa: ** Gio 25 Lug 2013 01:00:00 GMT + 0100 ** Notare il ** 01: 00: 00 **. Grazie. – brg

+0

L'output di un 'momento' non elaborato sulla console non è molto utile. Probabilmente stai guardando una delle sue proprietà interne. Dovresti formattarlo prima di controllare i risultati. Ad esempio 'moment.utc(). Format()' o 'moment(). Format()'. –

Problemi correlati