2016-01-13 9 views
7

Se si prende il seguente:Perché la data di 2/8888/2016 è valida in IE e Firefox?

var s = "2/8888/2016"; 
var d = new Date(s); 
alert(d); 

In Chrome, si otterrà:

Invalid Data

Ma in IE e Firefox, si otterrà:

Fri 01 giu 2040 00:00:00 GMT-0500 (ora legale centrale)

Sembra che aggiunga 8888 giorni a 1 febbraio. Invece, mi aspetto che la data venga considerata non valida. C'è un modo per far sì che FireFox e IE pensino che questa stringa di date non sia valida?

+0

Si può sempre controllare il numero dividendo la stringa e controllando se '8888' è maggiore di 31 – Derek

+0

anche, a causa dei problemi di' time' in javascript (proprio come java, lol), io uso: http://momentjs.com/ per colmare il divario. – Derek

+0

@DerekPollard fallisce il 31/11 e come bonus si arriva a scrivere la propria logica dell'anno bisestile. – djechlin

risposta

3

Risposta breve:

E 'un misbehaviuor dei browser che stai citano.

È necessario controllare la data nel formato corretto per conto proprio.Ma è abbastanza banale, suggerisco questo approccio:

Split data nell'anno y, mese m, giorno d e creare l'oggetto Date:

var date = new Date(y, m - 1, d); // note that month is 0 based 

quindi confrontare i valori originali con i logiche valori ottenuti utilizzando i metodi Date:

var isValid = date.getDate() == d && 
       date.getMonth() == m-1 && 
       date.getFullYear() == y; 

Prima di fare tutto questo si consiglia di controllare se la stringa data è valida per qualsiasi del browser:

Detecting an "invalid date" Date instance in JavaScript



Risposta lunga:

Firefox (e IE) accettando "2/8888/2016 "come un corretto formato di stringa sate sembra essere un bug/comportamento scorretto.

Infatti secondo ECMAScript 2015 Language Specification quando Date() viene richiamato con un singolo argomento stringa dovrebbe comportarsi come Date.parse()

http://www.ecma-international.org/ecma-262/6.0/#sec-date-value

Quest'ultimo

tentativi per analizzare il formato della stringa in base alle regole (compresi gli anni estesi) richiamati in Formato stringa data e ora (20.3.1.16)

..che è specificato qui

http://www.ecma-international.org/ecma-262/6.0/#sec-date-time-string-format

dove si può leggere

Il formato è il seguente: YYYY-MM-GGTHH: mm: ss.sssZ

[...]

MM è il mese dell'anno dal 01 (gennaio) t o 12 (dicembre).

GG è il giorno del mese dalle 01 alle 31.


Sembra che Firefox è interpretare il valore della stringa come quando Date() viene richiamato con più argomenti.

Da

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date

Nota: Dove Data si chiama come un costruttore con più di un argomento, se i valori sono superiori la loro gamma di logica (ad esempio 13 è fornito come il valore del mese o 70 per il valore minuto), il valore adiacente verrà regolato. Per esempio. new Date (2013, 13, 1) equivale a new Date (2014, 1, 1), entrambi creano una data per il 2014-02-01 (si noti che il mese è basato su 0). Analogamente per altri valori: new Date (2013, 2, 1, 0, 70) equivale a new Date (2013, 2, 1, 1, 10) che entrambi creano una data per 2013-03-01T01: 10: 00.

Questo potrebbe spiegare come "2/8888/2016" si trasforma in 2040-05-31T22:00:00.000Z

+0

Hai erroneamente interpretato quell'articolo di MDN. In questo caso, * Data * viene chiamato con un argomento stringa, quindi sono le regole per [* Date.parse *] (http://www.ecma-international.org/ecma-262/6.0/#sec- date.parse) utilizzati: "* Se Type (v) è String, quindi tv deve essere il risultato dell'analisi di v come data, esattamente nello stesso modo del metodo di analisi ... *". – RobG

+0

"'* 2/8888/2016' è un formato corretto per la creazione di un oggetto Date *" è nel migliore dei casi fuorviante.Ciò causerà un comportamento dipendente dall'implementazione (come scoperto dall'OP) e non è coerente con alcun formato specificato in ECMA-262 o accettato dai browser in uso. Né è una stringa di data valida poiché 8888 non è un numero di mese o giorno valido. Pertanto è difficile giustificare chiamandolo "corretto" in qualsiasi contesto. – RobG

+0

@RobG hai ragione. Quasi riscrivo la mia risposta. Grazie per avermi segnalato le specifiche della lingua ECMA. – Paolo

1

Non c'è alcun modo per rendere IE e FF pensano che sia valida, ad eccezione di:

  • si potrebbe cambiare le loro implementazioni JavaScript
  • si utilizza una libreria invece a che fare con questo.

Possiamo anche aspettarci che Javascript, come lingua, si evolva e possiamo incrociare le dita che i browser decidono di seguire una specifica più rigida. Il problema, naturalmente, è che ogni "correzione" deve essere retrocompatibile con le versioni precedenti della lingua (non succede sempre, Perl per esempio).

Quindi la cosa migliore ora è usare una libreria come momentjs come suggerito da Derek nei commenti del post.

+0

Questo è quello che ho pensato, ma volevo verificare che non ci fosse qualcosa di ovvio che mi mancava o che potevo fare. Grazie! – lhan

0

Hai incappato in ancora un altro motivo per cui si dovrebbe analizzare manualmente stringhe di data.

Quando Date viene fornito un argomento a stringa singola, viene considerato come una stringa di data e analizzato in base alle regole in Date.parse. Le regole lì prima tentano di analizzarlo come ISO 8601 format string. Se ciò non funziona, potrebbe ricadere su qualsiasi algoritmo di analisi che desidera.

Nel caso di "2/8888/2016", i browser tenteranno innanzitutto di analizzarlo come un formato ISO e falliranno. Sembra dalla sperimentazione che IE e Firefox determinano che la stringa è nel formato mese/giorno/anno e chiamano in modo efficace alla Data costruttore con:

new Date(2016,1,8888); 

Tuttavia, altri browser possono tentare di convalidare i valori e decidono che 8888 è non una data o un mese validi, quindi restituire una data non valida. Entrambe le risposte sono conformi all'ECMA-262.

Il miglior consiglio è quello di analizzare sempre manualmente le stringhe di data (una libreria può aiutare, ma in genere non è necessaria come una funzione di analisi personalizzata con la convalida di 3 righe di codice) quindi si può essere certi di risultati coerenti in qualsiasi browser o ambiente host.

Problemi correlati