Controlla se una stringa è un valore di data


207

Qual è un modo semplice per verificare se un valore è una data valida, è ammesso qualsiasi formato di data noto.

Per esempio ho i valori 10-11-2009, 10/11/2009, 2009-11-10T07:00:00+0000che deve essere rilevato come valori di data, ei valori 200, 10, 350, che non dovrebbero essere riconosciute come valore data. Qual è il modo più semplice per verificarlo, se è possibile? Perché anche i timestamp sarebbero consentiti.


Risposte:


41

Sarebbe Date.parse()sufficiente?

Vedere la relativa pagina della documentazione MDN .


24
Fai attenzione poiché restituirà comunque il reso per le date non valide a febbraio, ad esempio: 31-02-2013
leojh

58
Un altro motivo per stare attenti: i numeri vengono analizzati come date. Date.parse("4.3")lo è 986270400000.
Mogsdad,

Ho provato un violino con entrambi i casi di "cautela" sopra: console.log (Date.parse ("2013-02-31")); console.log (Date.parse ( "4.3")); e in entrambi i casi (su firefox) ha restituito NaN, quindi per me Date.parse sembra OK (sto comunque convalidando per i trattini e la lunghezza corretta prima dell'analisi).
Cloudranger

55
Scusa @Asmor, questa non è una risposta corretta. Date.parse analizzerà qualsiasi stringa contenente un numero.
jwerre

11
Date.parse ("My Name 8") sta arrivando come 99662040000 che è sbagliato. L'ho usato e ora soffro.
Rohith,

250

Aggiornamento 2015

È una vecchia domanda ma altre nuove domande come:

chiuso come duplicati di questo, quindi penso che sia importante aggiungere alcune nuove informazioni qui. Lo sto scrivendo perché mi sono spaventato pensando che le persone effettivamente copiano e incollano parte del codice pubblicato qui e lo usano nella produzione.

La maggior parte delle risposte qui o usano espressioni regolari complesse che corrispondono solo ad alcuni formati molto specifici e lo fanno effettivamente in modo errato (come la corrispondenza del 32 gennaio senza corrispondere alla data ISO effettiva come pubblicizzata - vedi la demo ) o provano a passare qualsiasi cosa al Datecostruttore e auguro il meglio.

Utilizzando Moment

Come ho spiegato in questa risposta, al momento è disponibile una libreria per questo: Moment.js

È una libreria per analizzare, convalidare, manipolare e visualizzare le date in JavaScript, che ha un'API molto più ricca delle funzioni standard di gestione delle date JavaScript.

È ridotto a 12kB / compresso con gzip e funziona in Node.js e in altri luoghi:

bower install moment --save # bower
npm install moment --save   # npm
Install-Package Moment.js   # NuGet
spm install moment --save   # spm
meteor add momentjs:moment  # meteor

Usando Moment puoi essere molto specifico sul controllo delle date valide. A volte è molto importante aggiungere alcuni indizi sul formato che ti aspetti. Ad esempio, una data come 22/06/2015 sembra una data valida, a meno che non si utilizzi un formato GG / MM / AAAA, nel qual caso tale data deve essere respinta in quanto non valida. Ci sono alcuni modi in cui puoi dire a Moment quale formato ti aspetti, ad esempio:

moment("06/22/2015", "MM/DD/YYYY", true).isValid(); // true
moment("06/22/2015", "DD/MM/YYYY", true).isValid(); // false

L' trueargomento è lì, quindi Moment non proverà ad analizzare l'input se non si conforma esattamente a uno dei formati forniti (secondo me dovrebbe essere un comportamento predefinito).

È possibile utilizzare un formato fornito internamente:

moment("2015-06-22T13:17:21+0000", moment.ISO_8601, true).isValid(); // true

E puoi usare più formati come un array:

var formats = [
    moment.ISO_8601,
    "MM/DD/YYYY  :)  HH*mm*ss"
];
moment("2015-06-22T13:17:21+0000", formats, true).isValid(); // true
moment("06/22/2015  :)  13*17*21", formats, true).isValid(); // true
moment("06/22/2015  :(  13*17*21", formats, true).isValid(); // false

Vedi: DEMO .

Altre biblioteche

Se non vuoi usare Moment.js, ci sono anche altre librerie:

Aggiornamento 2016

Ho creato il modulo immoment che è simile a (un sottoinsieme di) Moment ma senza sorprese causate dalla mutazione di oggetti esistenti (vedi i documenti per maggiori informazioni).

Aggiornamento 2018

Oggi raccomando di usare Luxon per la manipolazione di data / ora anziché Moment, che (a differenza di Moment) rende immutabili tutti gli oggetti, quindi non ci sono brutte sorprese legate alla mutazione implicita delle date.

Ulteriori informazioni

Guarda anche:

Una serie di articoli di Rob Gravelle sulle librerie di analisi della data JavaScript:

Linea di fondo

Ovviamente chiunque può provare a reinventare la ruota, scrivere un'espressione regolare (ma per favore leggi ISO 8601 e RFC 3339 prima di farlo) o chiama i costruttori incorporati con dati casuali per analizzare i messaggi di errore come 'Invalid Date'(Sei sicuro che questo messaggio sia esattamente lo stesso su tutte le piattaforme? In tutte le versioni locali? In futuro?) oppure puoi usare una soluzione testata e usare il tuo tempo per migliorarla, non reinventarla. Tutte le librerie elencate qui sono software libero e open source.


4
come si dovrebbe usare esattamente questo? moment("whatever 123").isValid()ritorna true.
Krivar,

4
@krivar È meglio usarlo in questo modo: moment("06/22/2015", "DD/MM/YYYY", true).isValid();con il formato della data previsto esplicitamente fornito e con un argomento che truesignifica controllo rigoroso. Ho aggiornato la mia risposta con maggiori informazioni ed esempi migliori.
rsp,

2
Lo stesso però, ma sto convalidando l'input dell'utente e non conosco il formato della data prevista ...
Jan Van der Haegen,

3
@JanVanderHaegen Se si possono ipotizzare che 3/4/5 sia una data valida e quindi è il 1 ° aprile 2015, consiglierei di aggiungere quei formati (e potenzialmente molto altro) a un elenco esplicito di formati supportati. Nota che 3/4/5 che hai citato è ambiguo senza un formato esplicito.
rsp,

3
Questa potrebbe essere la risposta migliore e più ben mantenuta che abbia mai visto su SO
Phil3992,

63

Ecco come ho risolto questo problema in un'app a cui sto lavorando in questo momento:

aggiornato in base al feedback di Krillgar:

var isDate = function(date) {
    return (new Date(date) !== "Invalid Date") && !isNaN(new Date(date));
}

5
Ho dovuto restituire (nuova data (data)). AString ()! == "Data non valida" per il nodo. Si noti anche che? true: false è ridondante. semplicemente restituire l'espressione sarà sufficiente qui.
domenukk,

In IE8, new Date(date)non ti dà 'Data non valida'.
Krillgar,

13
Questa non è una buona risposta new Date(date) !== "Invalid Date"sarà sempre tornare vero poiché l'espressione sinistra restituirà un oggetto Date con un TimeValue di NaN , che non può mai essere ===in una stringa. Utilizzo di =="works" a causa della conversione del tipo. Ma dal momento che l'analisi delle stringhe di date dipende ancora in larga misura dall'implementazione, basandoci su di essa per analizzare i formati casuali ci siamo seriamente imperfetti.
RobG

4
nuova data ("469") risultati martedì 01 gennaio 469 00:00:00 GMT + 0200 (EET)
Dan Ochiana

3
Questo è simile alla risposta erroneamente accettata. isDate('Mac OS X 10.14.2')ritorna vero qui.
BradStell,

24

new Date(date) === 'Invalid Date'funziona solo con Firefox e Chrome. IE8 (quello che ho sulla mia macchina a scopo di test) dà NaN.

Come indicato alla risposta accettata, Date.parse(date)funzionerà anche per i numeri. Quindi, per ovviare a questo, puoi anche verificare che non sia un numero (se è qualcosa che vuoi confermare).

var parsedDate = Date.parse(date);

// You want to check again for !isNaN(parsedDate) here because Dates can be converted
// to numbers, but a failed Date parse will not.
if (isNaN(date) && !isNaN(parsedDate)) {
    /* do your work */
}

2
Mi rendo conto che è un paio d'anni dopo, ma isNannon è una funzione; caso errato in prima istanza.
Tim Lewis,

Non funziona. In datetal caso Foostreet 1, la tua condizione viene valutata come vera.
Fabian Picone,

9

Che ne dici di questo? Verificherà se si tratta di un oggetto Date o una stringa di date:

function isDate(value) {
    var dateFormat;
    if (toString.call(value) === '[object Date]') {
        return true;
    }
    if (typeof value.replace === 'function') {
        value.replace(/^\s+|\s+$/gm, '');
    }
    dateFormat = /(^\d{1,4}[\.|\\/|-]\d{1,2}[\.|\\/|-]\d{1,4})(\s*(?:0?[1-9]:[0-5]|1(?=[012])\d:[0-5])\d\s*[ap]m)?$/;
    return dateFormat.test(value);
}

Devo dire che questo non verifica le stringhe formattate ISO ma con un po 'più di lavoro su RegExp dovresti essere bravo.


7

Nessuna delle risposte qui risolve il problema se la data non è valida, ad esempio il 31 febbraio. Questa funzione risolve il problema verificando che il mese restituito sia equivalente al mese originale e assicurandosi che sia stato presentato un anno valido.

//expected input dd/mm/yyyy or dd.mm.yyyy or dd-mm-yyyy
function isValidDate(s) {
  var separators = ['\\.', '\\-', '\\/'];
  var bits = s.split(new RegExp(separators.join('|'), 'g'));
  var d = new Date(bits[2], bits[1] - 1, bits[0]);
  return d.getFullYear() == bits[2] && d.getMonth() + 1 == bits[1];
} 

Perché la domanda non è quella di verificare se una stringa è una data "valida", ma solo il controllo di una stringa rappresenta un formato data.
Thizzer,

@Thizzer buon punto. Non mi dispiacerebbe risolvere, ma rileggendo la tua domanda sono sconcertato perché dici che 10 non dovrebbe convalidare ma che i timestamp dovrebbero essere consentiti.
ykay dice Reinstate Monica il

xD non l'aveva nemmeno notato, una domanda dei miei giorni precedenti con data / timestamp. Proverò a modificare la domanda più tardi oggi.
Thizzer,

perché mese-1 e quindi mese + 1?
Kapil Raghuwanshi,

Le date javascript di @KapilRaghuwanshi usano un mese in base zero, quindi è necessario sottrarre 1 per creare la data corretta e aggiungere 1 per verificare se è equivalente al mese originale
ykay dice Reinstate Monica

5

Utilizzare l'espressione regolare per convalidarlo.

isDate('2018-08-01T18:30:00.000Z');

isDate(_date){
        const _regExp  = new RegExp('^(-?(?:[1-9][0-9]*)?[0-9]{4})-(1[0-2]|0[1-9])-(3[01]|0[1-9]|[12][0-9])T(2[0-3]|[01][0-9]):([0-5][0-9]):([0-5][0-9])(.[0-9]+)?(Z)?$');
        return _regExp.test(_date);
    }

4

Facendo riferimento a tutti i commenti di cui sopra, sono arrivato a una soluzione.

Funziona se il Datepassaggio è in formato ISO o deve essere manipolato per altri formati.

var isISO = "2018-08-01T18:30:00.000Z";

if (new Date(isISO) !== "Invalid Date" && !isNaN(new Date(isISO))) {
    if(isISO == new Date(isISO).toISOString()) {
        console.log("Valid date");
    } else {
        console.log("Invalid date");
    }
} else {
    console.log("Invalid date");
}

Puoi giocare qui su JSFiddle.


1
Questa soluzione ha funzionato meglio per me poiché le stringhe di date supportate dalla mia app sono nel formato YYYY-MM-DD, quindi è banale collegarle T00:00:00.000Ze utilizzare questa soluzione per verificare la presenza di stringhe valide.
Accelerare il

per javascript funziona, ma come si usa in dattiloscritto?
Sae,

3

Ecco una funzione migliorata che utilizza solo Date.parse():

function isDate(s) {
    if(isNaN(s) && !isNaN(Date.parse(s)))
        return true;
    else return false;
}

Nota: Date.parse () analizzerà i numeri: ad esempio Date.parse(1)restituirà una data. Quindi qui controlliamo se snon è un numero, se è una data.


1
questo non funziona poiché il superamento di "test 2" passerà come una data vera. testato nell'ultima versione di chrome
user1751287

2

Vorrei fare questo

var myDateStr= new Date("2015/5/2");

if( ! isNaN ( myDateStr.getMonth() )) {
    console.log("Valid date");
}
else {
    console.log("Invalid date");
}

Gioca qui


2
Questo non funziona nell'attuale Chrome, probabilmente in altri browser. Ho cambiato la stringa fornita EXAMPLE STRING 12345e restituisce "Data valida".

1

Ecco una versione minimalista.

var isDate = function (date) {
    return!!(function(d){return(d!=='Invalid Date'&&!isNaN(d))})(new Date(date));
}

1
Non funziona ancora per il mio esempio:isDate("  1")
Tomas,

@ Tom Dovresti verificare se il valore contiene caratteri di spazi bianchi prima di determinare se è una data. Il problema è un caso speciale che deve essere gestito dalla logica del controller.
Mr. Polywhirl,

1
Non è necessario verificare la presenza di caratteri di spazi bianchi poiché la stringa del 1 gennaio 2020 è una data valida che contiene spazi bianchi. Il tuo metodo non tiene conto di questo.
Kirstin Walsh, il

1

Questa funzione richiamabile funziona perfettamente, restituisce vero per data valida. Assicurati di chiamare utilizzando una data in formato ISO (aaaa-mm-gg o aaaa / mm / gg):

function validateDate(isoDate) {

    if (isNaN(Date.parse(isoDate))) {
        return false;
    } else {
        if (isoDate != (new Date(isoDate)).toISOString().substr(0,10)) {
            return false;
        }
    }
    return true;
}

1
È buono, ma non risponde completamente alla domanda. In particolare, non funziona per "2009-11-10T07: 00: 00 + 0000", uno degli esempi forniti.
amadan,

Non pensare che funzioni come dovrebbe convalidare Data ('30-12-2018T08: 00: 00.000Z') // false
Jose Browne,

Indipendentemente dal fatto che funzioni o meno, potrebbe essere semplificato comereturn !isNaN(Date.parse(isoDate)) || isoDate == new Date(isoDate).toISOString().substr(0,10);
Michel Jung,

1

So che è una vecchia domanda, ma ho affrontato lo stesso problema e ho visto che nessuna delle risposte ha funzionato correttamente, in particolare eliminando i numeri (1.200.345, ecc.) Dalle date, che è la domanda originale. Ecco un metodo piuttosto non ortodosso che mi viene in mente e sembra funzionare. Si prega di sottolineare se ci sono casi in cui fallirà.

if(sDate.toString() == parseInt(sDate).toString()) return false;

Questa è la linea per eliminare i numeri. Pertanto, l'intera funzione potrebbe apparire come:

function isDate(sDate) {  
  if(sDate.toString() == parseInt(sDate).toString()) return false; 
  var tryDate = new Date(sDate);
  return (tryDate && tryDate.toString() != "NaN" && tryDate != "Invalid Date");  
}

console.log("100", isDate(100));
console.log("234", isDate("234"));
console.log("hello", isDate("hello"));
console.log("25 Feb 2018", isDate("25 Feb 2018"));
console.log("2009-11-10T07:00:00+0000", isDate("2009-11-10T07:00:00+0000"));


1
console.log("hello 1 ", isDate("hello 1 "));ritorna vero
Giovanni,

hai ragione! hai una soluzione? Fino ad ora penso che nessuna delle risposte qui abbia davvero affrontato la domanda in modo appropriato!
peekolo,

"100%", una percentuale, restituisce true
toddmo

0

va bene verificare se è disponibile una funzione relativa alla data affinché l'oggetto possa scoprire se si tratta di un oggetto Date o no?

piace

var l = new Date();
var isDate = (l.getDate !== undefined) ? true; false;

0

È così che finisco per farlo. Questo non coprirà tutti i formati. Devi adeguarti di conseguenza. Ho il controllo sul formato, quindi funziona per me

function isValidDate(s) {
            var dt = "";
            var bits = [];
            if (s && s.length >= 6) {
                if (s.indexOf("/") > -1) {
                    bits = s.split("/");
                }
                else if (s.indexOf("-") > -1) {
                    bits = s.split("-");
                }
                else if (s.indexOf(".") > -1) {
                    bits = s.split(".");
                }
                try {
                    dt = new Date(bits[2], bits[0] - 1, bits[1]);
                } catch (e) {
                    return false;
                }
                return (dt.getMonth() + 1) === parseInt(bits[0]);
            } else {
                return false;
            }
        }

-1

Ok, questa è una vecchia domanda, ma ho trovato un'altra soluzione durante il controllo delle soluzioni qui. Per me lavora per verificare se la funzione getTime () è presente nell'oggetto data:

const checkDate = new Date(dateString);

if (typeof checkDate.getTime !== 'function') {
  return;
}

-1

document.getElementById('r1').innerHTML = dayjs('sdsdsd').isValid()

document.getElementById('r2').innerHTML = dayjs('2/6/20').isValid()
<script src="https://unpkg.com/dayjs@1.8.21/dayjs.min.js"></script>

<p>'sdsdsd' is a date: <span id="r1"></span></p>
<p>'2/6/20' is a date: <span id="r2"></span></p>

Una libreria leggera è pronta per te: Day.js


1
Questo è fondamentalmente la pubblicità su StackOverflow, astenersi dal farlo.
c4sh

-4
SimpleDateFormat sdf = new SimpleDateFormat(dateFromat);
sdf.setLenient(false);

Per impostazione predefinita, questo è impostato su VERO. Quindi anche le stringhe di formato errato restituiscono buoni valori.

L'ho usato in questo modo:

SimpleDateFormat formatter = new SimpleDateFormat("yyyy/MM/dd");
formatter.setLenient(false);
String value = "1990/13/23"; 

try {
      Date date = formatter.parse(value);
      System.out.println(date);
    }catch (ParseException e) 
  {
    System.out.println("its bad");
  }

5
... javascript ?!
artparks,

-5

Prova questo:

if (var date = new Date(yourDateString)) {
    // if you get here then you have a valid date       
}

6
Questo non funziona per me. Innanzitutto il var nella condizione non viene analizzato, ma se lo rimuovi e provi qualcosa del genere: if (date = new Date ("immondizia")) {alert (date); } Anche se la data è spazzatura, l'avviso verrà comunque eseguito poiché la funzione Data restituirà "Data non valida" (almeno su Firefox), quindi la condizione viene valutata come vera. Immagino che se alcuni browser restituiscono null in una data non valida, funzionerebbe su quei browser. Potrebbe esserci un'incoerenza del browser qui.
Cloudranger
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.