yyyy - Rilevazione di una data "data non valida" istanza in JavaScript




javascript date timezone (20)

Vorrei dire la differenza tra oggetti data validi e non validi in JS, ma non sono riuscito a capire come:

var d = new Date("foo");
console.log(d.toString()); // shows 'Invalid Date'
console.log(typeof d); // shows 'object'
console.log(d instanceof Date); // shows 'true'

Qualche idea per scrivere una funzione isValidDate ?

  • Ash ha raccomandato Date.parse per le stringhe di data di analisi, che fornisce un modo autorevole per verificare se la stringa di data è valida.
  • Quello che preferirei, se possibile, è che la mia API accetti un'istanza di Data e che sia in grado di verificare / affermare se è valida o meno. La soluzione di Borgar lo fa, ma ho bisogno di testarlo attraverso i browser. Mi chiedo anche se ci sia un modo più elegante.
  • Ash mi ha fatto pensare di non avere la mia API per accettare le Date , sarebbe più facile da convalidare.
  • Borgar ha suggerito di testare un'istanza di Date e quindi di testare il valore temporale della Date . Se la data non è valida, il valore temporale è NaN . Ho controllato con ECMA-262 e questo comportamento è nello standard, che è esattamente quello che sto cercando.

Puoi semplicemente usare moment.js

Ecco un esempio:

var m = moment('2015-11-32', 'YYYY-MM-DD');
m.isValid(); // false

La sezione di convalida nella documentazione è abbastanza chiara.

Inoltre, i seguenti flag di analisi generano una data non valida:

  • overflow : un overflow di un campo data, ad esempio un tredicesimo mese, un trentaduesimo giorno del mese (o un ventinovesimo febbraio in un anno non bisestile), un 367esimo giorno dell'anno, ecc., l'overflow contiene l'indice dell'invalido unità per abbinare #invalidAt (vedi sotto); -1 significa nessun overflow.
  • invalidMonth : nome del mese non valido, ad esempio momento ('Marbruary', 'MMMM') ;. Contiene la stringa del mese non valida o altrimenti null.
  • empty : una stringa di input che non contiene nulla analizzabile, ad esempio il momento ('this is senza senso') ;. Booleano.
  • Eccetera.

Fonte: http://momentjs.com/docs/


È possibile verificare la validità di un oggetto Date d tramite

d instanceof Date && isFinite(d)

Per evitare problemi di cross-frame, si potrebbe sostituire l' instanceof check con

Object.prototype.toString.call(d) === '[object Date]'

Una chiamata a getTime() come nella risposta di Borgar non è necessaria poiché isNaN() e isFinite() converte entrambi implicitamente in numero.


Date object to string è un modo più semplice e affidabile per rilevare se entrambi i campi sono validi. Ad esempio, se si inserisce "-------" nel campo di inserimento della data. Alcune delle risposte di cui sopra non funzioneranno.

jQuery.validator.addMethod("greaterThan", 

    function(value, element, params) {
        var startDate = new Date($(params).val());
        var endDate = new Date(value);

        if(startDate.toString() === 'Invalid Date' || endDate.toString() === 'Invalid Date') {
            return false;
        } else {
            return endDate > startDate;
        }
    },'Must be greater than {0}.');

Ecco come lo farei:

if (Object.prototype.toString.call(d) === "[object Date]") {
  // it is a date
  if (isNaN(d.getTime())) {  // d.valueOf() could also work
    // date is not valid
  } else {
    // date is valid
  }
} else {
  // not a date
}

Aggiornamento [2018-05-31] : Se non ti occupi degli oggetti Date da altri contesti JS (finestre esterne, frame o iframe), questa forma più semplice può essere preferita:

function isValidDate(d) {
  return d instanceof Date && !isNaN(d);
}

Ho scritto questa funzione. Passa un parametro stringa e determinerà se si tratta di una data valida o meno in base a questo formato "gg / MM / aaaa".

ecco un test

input: "hahaha", output: false.

input: "29/2/2000", output: true.

input: "29/2/2001", output: false.

function isValidDate(str) {
    var parts = str.split('/');
    if (parts.length < 3)
        return false;
    else {
        var day = parseInt(parts[0]);
        var month = parseInt(parts[1]);
        var year = parseInt(parts[2]);
        if (isNaN(day) || isNaN(month) || isNaN(year)) {
            return false;
        }
        if (day < 1 || year < 1)
            return false;
        if(month>12||month<1)
            return false;
        if ((month == 1 || month == 3 || month == 5 || month == 7 || month == 8 || month == 10 || month == 12) && day > 31)
            return false;
        if ((month == 4 || month == 6 || month == 9 || month == 11 ) && day > 30)
            return false;
        if (month == 2) {
            if (((year % 4) == 0 && (year % 100) != 0) || ((year % 400) == 0 && (year % 100) == 0)) {
                if (day > 29)
                    return false;
            } else {
                if (day > 28)
                    return false;
            }      
        }
        return true;
    }
}

In generale, rimango con qualunque sia l'impianto di Data nella pila del browser. Il che significa che riceverai sempre "Data non valida" quando chiami aDateString () in Chrome, Firefox e Safari alla data di questa risposta.

if(!Date.prototype.isValidDate){
  Date.prototype.isValidDate = function(){
    return this.toDateString().toLowerCase().lastIndexOf('invalid') == -1;
  };
}

Non ho provato questo in IE però.


Io uso il seguente codice per convalidare i valori per anno, mese e data.

function createDate(year, month, _date) {
  var d = new Date(year, month, _date);
  if (d.getFullYear() != year 
    || d.getMonth() != month
    || d.getDate() != _date) {
    throw "invalid date";
  }
  return d;
}

Per dettagli, fare riferimento a Verifica data in javascript


Ispirato dall'approccio di Borgar, mi sono assicurato che il codice non solo confermasse la data, ma in realtà assicurasse che la data fosse una data reale, il che significa che date come 31/09/2011 e 29/02/2011 non sono consentite.

function(dateStr) {
    s = dateStr.split('/');
    d = new Date(+s[2], s[1]-1, +s[0]);
    if (Object.prototype.toString.call(d) === "[object Date]") {
        if (!isNaN(d.getTime()) && d.getDate() == s[0] && 
            d.getMonth() == (s[1] - 1)) {
            return true;
        }
    }
    return "Invalid date!";
}

La risposta selezionata è eccellente, e la sto usando anche io. Tuttavia, se stai cercando un modo per convalidare l'input della data utente, devi essere consapevole del fatto che l'oggetto Date è molto persistente nel rendere quelli che potrebbero sembrare argomenti di costruzione non validi in argomenti validi. Il seguente codice di test unitario illustra il punto:

QUnit.test( "valid date test", function( assert ) {
  //The following are counter-examples showing how the Date object will 
  //wrangle several 'bad' dates into a valid date anyway
  assert.equal(isValidDate(new Date(1980, 12, 15)), true);
  d = new Date();
  d.setFullYear(1980);
  d.setMonth(1);
  d.setDate(33);
  assert.equal(isValidDate(d), true);
  assert.equal(isValidDate(new Date(1980, 100, 150)), true);
  //If you go to this exterme, then the checker will fail
  assert.equal(isValidDate(new Date("This is junk")), false);
  //This is a valid date string
  assert.equal(isValidDate(new Date("November 17, 1989")), true);
  //but is this?
  assert.equal(isValidDate(new Date("November 35, 1989")), false);  
  //Ha!  It's not.  So, the secret to working with this version of 
  //isValidDate is to pass in dates as text strings... Hooboy
  //alert(d.toString());
});

Mi è piaciuto molto l'approccio di Christoph (ma non avevo abbastanza reputazione per votarlo). Per il mio uso, so che avrò sempre un oggetto Date, quindi ho appena esteso la data con un metodo valido ().

Date.prototype.valid = function() {
  return isFinite(this);
}

Ora posso solo scrivere questo ed è molto più descrittivo di un semplice controllo di isFinite nel codice ...

d = new Date(userDate);
if (d.valid()) { /* do stuff */ }

Nessuna di queste risposte ha funzionato per me (testata in Safari 6.0) durante il tentativo di convalidare una data come 31/2/2012, tuttavia, funzionano bene quando si prova una data superiore a 31.

Quindi ho dovuto forzare la forza un po '. Supponendo che la data sia nel formato mm/dd/yyyy . Sto usando la risposta @broox:

Date.prototype.valid = function() {
    return isFinite(this);
}    

function validStringDate(value){
    var d = new Date(value);
    return d.valid() && value.split('/')[0] == (d.getMonth()+1);
}

validStringDate("2/29/2012"); // true (leap year)
validStringDate("2/29/2013"); // false
validStringDate("2/30/2012"); // false

Penso che parte di questo sia un processo lungo. Possiamo tagliare corto come mostrato di seguito:

 function isValidDate(dateString) {
        debugger;
        var dateStringSplit;
        var formatDate;

        if (dateString.length >= 8 && dateString.length<=10) {
            try {
                dateStringSplit = dateString.split('/');
                var date = new Date();
                date.setYear(parseInt(dateStringSplit[2]), 10);
                date.setMonth(parseInt(dateStringSplit[0], 10) - 1);
                date.setDate(parseInt(dateStringSplit[1], 10));

                if (date.getYear() == parseInt(dateStringSplit[2],10) && date.getMonth()+1 == parseInt(dateStringSplit[0],10) && date.getDate() == parseInt(dateStringSplit[1],10)) {
                    return true;
                }
                else {
                    return false;
                }

            } catch (e) {
                return false;
            }
        }
        return false;
    }

Per i progetti Angular.js puoi utilizzare:

angular.isDate(myDate);

Questo ha funzionato per me

new Date('foo') == 'Invalid Date'; //is true

Tuttavia questo non ha funzionato

new Date('foo') === 'Invalid Date'; //is false

Una funzione pronta basata sulla risposta più votata:

  /**
   * Check if date exists and is valid.
   *
   * @param {String} dateString Date in YYYY-mm-dd format.
   */
  function isValidDate(dateString) {
  var isValid = false;
  var date;

  date =
    new Date(
      dateString);

  if (
    Object.prototype.toString.call(
      date) === "[object Date]") {

    if (isNaN(date.getTime())) {

      // Date is unreal.

    } else {
      // Date is real if month and day match each other in date and string (otherwise may be shifted):
      isValid =
        date.getUTCMonth() + 1 === dateString.split("-")[1] * 1 &&
        date.getUTCDate() === dateString.split("-")[2] * 1;
    }
  } else {
    // It's not a date.
  }

  return isValid;
}

Vorrei ricordare che il widget DatePicker di jQuery UI ha un ottimo metodo di utilità per la validazione della data che controlla il formato e la validità (ad esempio, non sono consentite date 01/33/2013).

Anche se non vuoi utilizzare il widget datepicker sulla tua pagina come elemento dell'interfaccia utente, puoi sempre aggiungere la sua libreria .js alla tua pagina e quindi chiamare il metodo validator, passando il valore che vuoi convalidare. Per rendere la vita ancora più semplice, prende una stringa come input, non un oggetto Date JavaScript.

Vedi: http://api.jqueryui.com/datepicker/

Non è elencato come metodo, ma è lì ... come funzione di utilità. Cerca la pagina per "parsedate" e troverai:

$ .datepicker.parseDate (formato, valore, impostazioni) - Estrae una data da un valore di stringa con un formato specificato.

Esempio di utilizzo:

var stringval = '01/03/2012';
var testdate;

try {
  testdate = $.datepicker.parseDate('mm/dd/yy', stringval);
             // Notice 'yy' indicates a 4-digit year value
} catch (e)
{
 alert(stringval + ' is not valid.  Format must be MM/DD/YYYY ' +
       'and the date value must be valid for the calendar.';
}

(Maggiori informazioni su come specificare i formati delle date sono disponibili su http://api.jqueryui.com/datepicker/#utility-parseDate )

Nell'esempio sopra, non vedresti il ​​messaggio di avviso dal '01 / 03/2012 'è una data valida per il calendario nel formato specificato. Tuttavia, se hai reso 'stringval' uguale a '13 / 04/2013 ', ad esempio, riceverai il messaggio di avviso, poiché il valore '13 / 04/2013' non è valido per il calendario.

Se un valore di stringa passato viene analizzato correttamente, il valore di 'testdate' sarebbe un oggetto Date Javascript che rappresenta il valore di stringa passato. In caso contrario, sarebbe indefinito.


puoi convertire la data e l'ora in millisecondi getTime()

questo metodo getTime() restituisce Not a Number NaN quando non è valido

if(!isNaN(new Date("2012/25/255").getTime()))
  return 'valid date time';
  return 'Not a valid date time';

risposta più breve per verificare la data valida

if(!isNaN(date.getTime()))

// check whether date is valid
var t = new Date('2011-07-07T11:20:00.000+00:00x');
valid = !isNaN(t.valueOf());

IsValidDate: function(date) {
        var regex = /\d{1,2}\/\d{1,2}\/\d{4}/;
        if (!regex.test(date)) return false;
        var day = Number(date.split("/")[1]);
        date = new Date(date);
        if (date && date.getDate() != day) return false;
        return true;
}




date