2016-03-23 9 views
5

Come convalidare una data? Intendo non il formato, ma la logica. Ad esempio: 30 febbraio non è una data valida.La data Javascript consente dati non validi (ad esempio il 30 febbraio)

var date = new Date("2015-02-29T13:02:49.073Z"); // 2015 Feb 29th does not exist 
console.log(date.toISOString()); 

Returns 2015-03-01T13: 02: 49.073Z (1 ° marzo).

Ma voglio un'informazione che questa data (input) non è valida.

Modifica: Testato in Chrome. Firefox restituisce "data non valida". Ma non per l'analisi. Solo quando viene utilizzata la data (ad esempio toISOString()) viene generata un'eccezione.

try 
{ 
    var date = new Date("2015-02-29T13:02:49.073Z"); 
    console.log(date.toISOString()); 
} 
catch(e) 
{ 
    console.log("error: " + e.message); 
} 

Firefox:

data non valida

Chrome: (. Niente, appena passato alla data successiva)

Riepilogo: dipende dal browser. Quindi, non è raccomandato l'uso.

jsfiddle example

+0

arresto: Vedo ora che questo dipende dal browser. Firefox restituisce una data non valida e Chrome ignora e conta fino al giorno successivo. Ok ma questo è terribile. Devo scrivere una propria funzione per convalidare una stringa di data. (?) – Dominik

+0

_Non si consiglia di utilizzare Date.parse fino a ** ES5 **, l'analisi delle stringhe dipende interamente dall'implementazione. Ci sono ancora molte differenze nel modo in cui gli host eseguono le stringhe di data di parsing, quindi le stringhe di date dovrebbero essere analizzate manualmente (una libreria può aiutare se molti formati diversi devono essere adattati) ._ ([ref.] (Https: //developer.mozilla. org/it-it/Documenti/Web/JavaScript/Riferimento/Global_Objects/Data/analisi)) – hindmost

+0

C'è una domanda qui? La logica alla base del modo in cui il costruttore Date gestisce i vari argomenti è completamente documentata in [* ECMA-262 *] (http://ecma-international.org/ecma-262/6.0/index.html#sec-date-year- mese-giorno-ore-minuti-secondi-MS). Come convalidare una data (cioè i valori) è stata trattata in [* molte domande qui *] (http://stackoverflow.com/search?q=%5Bjavascript%5D+validate+a+date). – RobG

risposta

4

La cosa più semplice che posso pensare, è quello di convertire la data analizzato a stringa ISO e confrontarlo con l'ingresso originale:

var input = "2015-02-29T13:02:49.073Z" 
var date = new Date(input); 
var isValid = (input === date.toISOString()); 
+0

Sì, grazie per questo. Ho appena avuto la stessa idea. Funziona solo con lo stesso formato di stringa. Ma questo è esattamente ciò di cui ho bisogno. Ho già una regex per convalidare la stringa ISO. – Dominik

4

Io uso questa funzione per controllare se una data è valido o meno:

function isValidDate(year, month, day) { 
    month = month - 1; 
    var d = new Date(year, month, day); 
    if (d.getFullYear() == year && d.getMonth() == month && d.getDate() == day) { 
     return true; 
    } 
    return false; 
} 
+0

Sì, penso anche che devi farlo. Solo per analizzare con Date() non è abbastanza. :) – Dominik

+0

Nota Potrebbe essere necessario normalizzare e aggiungere il fuso orario/l'ora legale a questo codice come indicato nella mia risposta – mplungjan

+0

@ mplungjan-daylight saving può essere ignorato per le date (a condizione che il browser non abbia bug). È necessario testare solo il mese (poiché una data al di fuori dell'intervallo del mese e un mese compreso tra 1 e 12 inclusi comporterà * getMonth * che restituisce un numero di mese diverso). – RobG

0

ho trovato che il comportamento piuttosto divertente. Ho appena convertito l'input in una data (come hai fatto), quindi aggiorno il testo nella casella di testo per mostrare la data come interpretata da JavaScript in modo che l'utente possa vedere la data (valida) risultante.

Fortunatamente, ora possiamo fare molto meglio. Moment.js è una fantastica libreria per gestire i valori di data/ora in JavaScript. Di certo ha reso la vita molto più facile per me!

http://momentjs.com/

0

date nei browser sono sempre molto difficile, ho suggerisco di utilizzare un JS lib come momento: http://momentjs.com/

quindi è possibile utilizzare .isValid() metodo per es .:

moment('03:55', 'HH:mm').isValid(); 
moment('2012-05-25', 'YYYY-MM-DD').isValid(); 
moment('2015-02-29T13:02:49.073Z', "YYYY-MM-DDTHH:mm:ss", true).isValid(); 
+0

per quanto vedo non è stato suggerito affatto. – thegio

+0

Ho messo un esempio. – thegio

+0

guarda meglio .... – thegio

0

Se si passa una stringa che inizia con il formato 'AAAA-MM', come hai in questione, è possibile utilizzare questa funzione:

function makeDate(s) { 
    var date = new Date(s); 
    if (date.toISOString(date).substr(0,7) != s.substr(0,7)) throw "Invalid date"; 
    return date; 
} 

dt = makeDate('2015-02-29T13:02:49.073Z'); 

Questa funzione makeDate sostituirebbe la pianura new Date(...) chiamata, ma genererà anche un errore in Chrome quando viene passata una stringa di data non valida.

2

Ho scritto piccola funzione per voi:

function check_date(str){ 
    try{ 
     return str == new Date(str).toISOString() 
    }catch(e){ 
     return false; 
    } 
} 

Prova questa

console.log(check_date('2015-02-01T13:02:49.073Z')); 
console.log(check_date('2015-02-35T13:02:49.073Z')); 
console.log(check_date('2015-02-29T13:02:49.073Z')); 

https://jsfiddle.net/8o040ctr/

+0

@trincot Penso che abbia risposto in un modo che funzionerà con qualsiasi browser – mplungjan

+0

Hai ragione, ho perso il punto della risposta :-) – trincot