2015-11-25 29 views
19

Ho una stringa che rappresenta l'ora corrente: 2015-11-24T19:40:00. Come analizzare questa stringa in Javascript per ottenere una data rappresentata da questa stringa come LOCAL TIME? A causa di alcune restrizioni, non posso usare la libreria moment, ma jquery è permesso. So che qualcuno ha già fatto questa domanda, ma la risposta è stata utilizzata momentJavascript: analizza una stringa in data come fuso orario LOCAL

Ad esempio, se eseguo lo script in California, questa stringa rappresenterebbe il tempo pacifico delle 7PM, ma se eseguo lo script in NY, questo la stringa rappresenterebbe il tempo orientale?

Ho provato quanto segue ma Chrome e Firefox darmi risultati diversi:

var str = "2015-11-24T19:40:00"; 
var date = new Date(str); 

Chrome consuma come UTC tempo (Tue Nov 24 2015 11:40:00 GMT-0800 (Pacific Standard Time)),

ma Firefox consuma come il mio locale PACIFIC time (Tue Nov 24 2015 19:40:00 GMT-0800 (Pacific Standard Time))

Ho provato ad aggiungere "Z" a str, ad esempio var date = new Date(str+"Z");, quindi entrambi i browser mi danno l'ora UTC. C'è una lettera simile a "Z" che dice a tutti i browser (almeno Chrome, Firefox e Safari) di analizzare la stringa come fuso orario locale?

risposta

29

L'analisi delle stringhe di data utilizzando il costruttore Date o Date.parse (che sono essenzialmente la stessa cosa) è fortemente raccomandata contro.

se la data è chiamato come una funzione e passato un formato ISO 8601 della data di stringa senza un fuso orario (come ad esempio 2015-11-24T19: 40: 00), si può ottenere uno dei seguenti risultati:

  1. pre ES5 implementaitons possono trattarlo come qualsiasi cosa, anche NaN (come IE 8)
  2. ES5 implementazioni compatibili tratterà come fuso orario UTC
  3. ECMAScript 2015 implementazioni compatibili saranno trattano come locale (che è coerente con la norma ISO 8601)

Un oggetto Date ha un valore temporale che è UTC e un offset in base alle impostazioni di sistema. Quando si invia una data all'output, ciò che viene visualizzato è solitamente il risultato di Date.prototype.toString, che è una stringa leggibile dall'implementazione, leggibile dall'uomo che rappresenta la data e l'ora, in genere in un fuso orario basato sulle impostazioni di sistema.

Il modo migliore per analizzare le stringhe di data è farlo manualmente. Se si ha la certezza che il formato è coerente e valida, quindi il parsing di una stringa formato ISO come una data locale è semplice come:

/* @param {string} s - an ISO 8001 format date and time string 
 
**      with all components, e.g. 2015-11-24T19:40:00 
 
** @returns {Date} - Date instance from parsing the string. May be NaN. 
 
*/ 
 
function parseISOLocal(s) { 
 
    var b = s.split(/\D/); 
 
    return new Date(b[0], b[1]-1, b[2], b[3], b[4], b[5]); 
 
} 
 

 
document.write(parseISOLocal('2015-11-24T19:40:00'));

Si noti che l'analisi delle stringhe ISO usando Date.parse accetta solo UTC, non accetta altre designazione del fuso orario (osservando il comportamento sopra se manca).

+0

Ottima risposta !!! –

+0

come una domanda a parte, 'new Date()' restituisce sempre un orario corrente locale? In caso contrario, come posso ottenere l'ora locale corrente? Almeno a me test lo fa per Chrome e Firefox. Fondamentalmente, ho bisogno di ottenere la differenza (in secondi) tra l'ora corrente e un dato tempo rappresentato dalla stringa, come '" 2015-11-24T19: 40: 00 "' – Simo

+1

Come sopra, 'new Date()' restituisce un oggetto Date con il suo valore temporale impostato sull'ora UTC corrente e un offset in base alle impostazioni di sistema. Il modo in cui viene presentato è determinato dal metodo chiamato: [* toString *] (http://www.ecma-international.org/ecma-262/6.0/#sec-date.prototype.tostring), [* toISOString *] (http://www.ecma-international.org/ecma-262/6.0/#sec-date.prototype.toisostring), [* toUTCString *] (http://www.ecma-international.org/ecma-262 /6.0/#sec-date.prototype.toutcstring), [* aLocaleTimeString *] (http://www.ecma-international.org/ecma-262/6.0/#sec-date.prototype.tolocaletimestring) ecc. – RobG

-1

Dove Data viene chiamata come costruttore con più di un argomento, gli argomenti specificati rappresentano l'ora locale.

Ho anche un modo molto più veloce rispetto all'uso del string.split() perché sappiamo già dove i numeri sono:

return new Date(Number(date.substring(0, 4)), Number(date.substring(5, 7))-1, 
       Number(date.substring(8, 10)), Number(date.substring(11, 13)), 
       Number(date.substring(14, 16)), Number(date.substring(17, 19))); 

Questo funziona con e/o senza la 'T' e 'Z 'stringhe e ha ancora prestazioni decenti. Ho aggiunto la conversione numerica esplicita (più veloce e migliore di parseInt), quindi compila anche in TypeScript. Numero

+0

davvero non dovrebbe essere difficile codificare – tcoulson

3

Una variazione sulla straordinaria risposta di RobG.

Nota che ciò richiederà di eseguire bleeding edge JavaScript come si basa sulla notazione freccia e operatore di diffusione.

function parseDateISOString(s) { 
    let ds = s.split(/\D/).map(s => parseInt(s)); 
    ds[1] = ds[1] - 1; // adjust month 
    return new Date(...ds); 
} 

Il vantaggio di questo approccio è che esso si applica automaticamente il corretto numero di argomenti passati. Se questo è quello che vuoi.

+0

@IAfanasov scusa, penso che devi elaborare un po 'di più. Non capisco cosa stai cercando di dire. –

+0

scusate, ho perso una riga di codice. – IAfanasov