Comprobar si una cadena es un valor de fecha

207

¿Cuál es una manera fácil de verificar si un valor es una fecha válida? Se permite cualquier formato de fecha conocido.

Por ejemplo, tengo los valores 10-11-2009, 10/11/2009, 2009-11-10T07:00:00+0000la que todos deben ser reconocidos como valores de fecha, y los valores 200, 10, 350, que no deben ser reconocidos como un valor de fecha. ¿Cuál es la forma más sencilla de verificar esto, si esto es posible? Porque las marcas de tiempo también estarían permitidas.

Thizzer
fuente

Respuestas:

41

Sería Date.parse()suficiente?

Consulte su página relativa de documentación de MDN .

Asmor
fuente
24
Tenga cuidado con esto, ya que aún devolverá la devolución de fechas no válidas en febrero, por ejemplo:
2013-02-31
58
Otra razón para tener cuidado: los números se analizan como fechas. Date.parse("4.3")es 986270400000.
Mogsdad
Intenté un violín con los dos casos de 'precaución' anteriores: console.log (Date.parse ("2013-02-31")); console.log (Date.parse ("4.3")); y en ambos casos (en firefox) devolvió NaN, por lo que para mí, Date.parse parece estar bien (estoy prevalidando los guiones y la longitud correcta antes del análisis de todos modos).
Cloudranger
55
Lo siento @Asmor, esta no es una respuesta correcta. Date.parse analizará cualquier cadena con un número en.
jwerre
11
Date.parse ("Mi nombre 8") viene como 99662040000, lo cual es incorrecto. Usé esto y ahora sufro.
Rohith
250

Actualización 2015

Es una pregunta antigua pero otras preguntas nuevas como:

se cierren como duplicados de este, así que creo que es importante agregar información fresca aquí. Lo escribo porque me asusté pensando que la gente realmente copia y pega parte del código publicado aquí y lo usa en producción.

La mayoría de las respuestas aquí o bien usar expresiones regulares complejas que responden a formatos sólo algunos muy específicos y de hecho lo hacen de forma incorrecta (como ajuste de 32 de enero, cuando no coincida con la fecha ISO real como se anuncia - ver demostración ) o que tratan de pasar nada al Dateconstructor y desear lo mejor.

Usando momento

Como expliqué en esta respuesta, actualmente hay una biblioteca disponible para eso: Moment.js

Es una biblioteca para analizar, validar, manipular y mostrar fechas en JavaScript, que tiene una API mucho más rica que las funciones estándar de manejo de fechas de JavaScript.

Tiene 12kB minified / gzipped y funciona en Node.js y otros lugares:

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 puede ser muy específico sobre la verificación de fechas válidas. A veces es muy importante agregar algunas pistas sobre el formato que espera. Por ejemplo, una fecha como 22/06/2015 parece una fecha válida, a menos que use un formato DD / MM / AAAA, en cuyo caso esta fecha debe rechazarse como no válida. Hay pocas maneras de decirle a Moment qué formato espera, por ejemplo:

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

El trueargumento está ahí, por lo que el Momento no intentará analizar la entrada si no se ajusta exactamente a uno de los formatos proporcionados (en mi opinión, debería ser un comportamiento predeterminado).

Puede usar un formato provisto internamente:

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

Y puede usar múltiples formatos como una matriz:

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

Ver: DEMO .

Otras bibliotecas

Si no desea usar Moment.js, también hay otras bibliotecas:

Actualización 2016

He creado el immoment módulo que es como (un subconjunto de) Momento pero sin sorpresas causadas por mutación de objetos existentes (véase la documentación para obtener más información).

Actualización 2018

Hoy recomiendo usar Luxon para la manipulación de fecha / hora en lugar de Moment, que (a diferencia de Moment) hace que todos los objetos sean inmutables, por lo que no hay sorpresas desagradables relacionadas con la mutación implícita de fechas.

Más información

Ver también:

Una serie de artículos de Rob Gravelle en las bibliotecas de análisis de fechas de JavaScript:

Línea de fondo

Por supuesto, cualquier persona puede tratar de reinventar la rueda, escribir una expresión regular (pero por favor, lea realmente la norma ISO 8601 y RFC 3339 antes de hacerlo) o llame al buit-en los constructores con datos aleatorios a los mensajes de error de análisis como 'Invalid Date'(¿Estás seguro de que este mensaje es exactamente igual en todas las plataformas, en todos los entornos locales, en el futuro, o puede usar una solución probada y usar su tiempo para mejorarla, no reinventarla. Todas las bibliotecas enumeradas aquí son de código abierto, software libre.

rsp
fuente
44
¿Cómo exactamente se debe usar esto? moment("whatever 123").isValid()vuelve true.
krivar
44
@krivar Es mejor usarlo así: moment("06/22/2015", "DD/MM/YYYY", true).isValid();con el formato de fecha esperado provisto explícitamente y con un argumento que truesignifica verificación estricta. Actualicé mi respuesta con más información y mejores ejemplos.
rsp
2
Lo mismo, pero estoy validando la entrada del usuario y no sé el formato de fecha esperado ...
Jan Van der Haegen
3
@ JanVanderHaegen Si se pueden hacer suposiciones de que 3/4/5 es una fecha válida y también lo es el 1 de abril de 2015, recomendaría agregar esos formatos (y potencialmente mucho más) a una lista explícita de formatos compatibles. Tenga en cuenta que 3/4/5 que mencionó es ambiguo sin un formato explícito.
rsp
3
Esta podría ser la respuesta mejor y mejor mantenida que he visto en SO
Phil3992
63

Así es como resolví este problema en una aplicación en la que estoy trabajando ahora:

actualizado en base a los comentarios de krillgar:

var isDate = function(date) {
    return (new Date(date) !== "Invalid Date") && !isNaN(new Date(date));
}
Neil Girardi
fuente
55
Necesitaba regresar (nueva fecha (fecha)). ToString ()! == "Fecha inválida" para el nodo. También tenga en cuenta que? verdadero: falso es redundante. simplemente devolver la expresión será suficiente aquí.
Domenukk
En IE8, new Date(date)no le da 'Fecha inválida'.
krillgar
13
Esta no es una buena respuesta. new Date(date) !== "Invalid Date"será siempre volver cierto ya que la expresión izquierda devolverá un objeto Date con un TimeValue de NaN , que nunca puede ser ===una cadena. Usando =="obras" debido a la conversión de tipos. Pero dado que el análisis de las cadenas de fecha todavía depende en gran medida de la implementación, depender de él para analizar formatos aleatorios con defectos serios.
RobG
44
La nueva fecha ("469") da como resultado el martes 01 de enero 469 00:00:00 GMT + 0200 (EET)
Dan Ochiana
3
Esto es similar a la respuesta correcta falsamente aceptada. isDate('Mac OS X 10.14.2')vuelve verdadero aquí.
BradStell
24

new Date(date) === 'Invalid Date'solo funciona en Firefox y Chrome. IE8 (el que tengo en mi máquina con fines de prueba) proporciona NaN.

Como se indicó a la respuesta aceptada, Date.parse(date)también funcionará para los números. Entonces, para evitar eso, también puede verificar que no sea un número (si eso es algo que desea confirmar).

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 */
}
krillgar
fuente
2
Me doy cuenta de que es un par de años después, pero isNanno es una función; caso incorrecto en primera instancia.
Tim Lewis
No funciona. Si datees así Foostreet 1, su condición se evalúa como verdadera.
Fabian Picone
9

¿Qué tal algo como esto? Probará si es un objeto Date o una cadena de fecha:

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);
}

Debo mencionar que esto no prueba las cadenas con formato ISO, pero con un poco más de trabajo para el RegExp debería ser bueno.

jwerre
fuente
7

Ninguna de las respuestas aquí se dirige a verificar si la fecha no es válida, como el 31 de febrero. Esta función se ocupa de verificar si el mes devuelto es equivalente al mes original y asegurarse de que se haya presentado un año válido.

//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];
} 
ykay dice reinstalar a Mónica
fuente
Porque la pregunta no es si verificar si una cadena es una fecha 'válida', sino simplemente verificar si una cadena representa un formato de fecha.
Thizzer
@Thizzer buen punto. No me importaría arreglarlo, pero al volver a leer su pregunta, estoy perplejo porque dice que 10 no debe validar, pero que se deben permitir las marcas de tiempo.
ykay dice Reinstate Monica
xD ni siquiera se dio cuenta de eso, una pregunta de mis días anteriores con fecha / hora. Intentaré editar la pregunta más tarde hoy.
Thizzer
¿Por qué mes-1 y luego mes + 1?
Kapil Raghuwanshi
Las fechas de JavaScript de @KapilRaghuwanshi usan un mes basado en cero, por lo que debe restar 1 para crear la fecha correcta y agregar 1 para verificar si es equivalente al mes original
ykay dice Mónica Restablecer
5

Use la expresión regular para validarlo.

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);
    }
lpradhap
fuente
4

Al referirme a todos los comentarios anteriores, he llegado a una solución.

Esto funciona si el Date pase está en formato ISO o necesita manipularse para otros formatos.

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");
}

Puedes jugar aquí en JSFiddle.

Nikhil Zurunge
fuente
1
Esta solución funcionó mejor para mí, ya que las cadenas de fecha que admite mi aplicación son del formato YYYY-MM-DD, por lo que es trivial adjuntar T00:00:00.000Zy usar esta solución para verificar cadenas válidas.
acelerar el
para javascript esto funciona, pero ¿cómo usarlo en mecanografiado?
Sae
3

Aquí hay una función mejorada que solo usa Date.parse():

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

Nota: Date.parse () analizará los números: por ejemplo Date.parse(1), devolverá una fecha. Así que aquí verificamos si sno es un número, si es una fecha.

A-Sharabiani
fuente
1
esto no funciona ya que pasar la 'prueba 2' pasará como una fecha verdadera. probado en la última versión de Chrome
user1751287
2

Yo haría esto

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

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

Juega aqui

kiranvj
fuente
2
Esto no funciona en Chrome actual, posiblemente en otros navegadores. Cambié la cadena proporcionada a EXAMPLE STRING 12345y devuelve "Fecha válida".
1

Aquí hay una versión minimalista.

var isDate = function (date) {
    return!!(function(d){return(d!=='Invalid Date'&&!isNaN(d))})(new Date(date));
}
Mr. Polywhirl
fuente
1
Todavía no funciona para mi ejemplo:isDate("  1")
Tomás
@Tom Debe verificar si el valor contiene caracteres de espacio en blanco antes de determinar si es una fecha. Su problema es un caso especial que debe ser manejado por la lógica de su controlador.
Sr. Polywhirl
1
No debería ser necesario verificar los espacios en blanco, ya que la cadena del 1 de enero de 2020 es una fecha válida que contiene espacios en blanco. Su método no tiene en cuenta esto.
Kirstin Walsh
1

Esta función invocable funciona perfectamente, devuelve verdadero para la fecha válida. Asegúrese de llamar utilizando una fecha en formato ISO (aaaa-mm-dd o aaaa / mm / dd):

function validateDate(isoDate) {

    if (isNaN(Date.parse(isoDate))) {
        return false;
    } else {
        if (isoDate != (new Date(isoDate)).toISOString().substr(0,10)) {
            return false;
        }
    }
    return true;
}
Peter DK
fuente
1
Es bueno, pero no responde la pregunta por completo. Específicamente, no funciona para '2009-11-10T07: 00: 00 + 0000', uno de los ejemplos dados.
amadan
No piense que esto funciona como debería validar Fecha ('2016-12-30T08: 00: 00.000Z') // falso
Jose Browne
Independientemente de si esto funciona o no, podría simplificarse comoreturn !isNaN(Date.parse(isoDate)) || isoDate == new Date(isoDate).toISOString().substr(0,10);
Michel Jung
1

Sé que es una pregunta antigua, pero enfrenté el mismo problema y vi que ninguna de las respuestas funcionó correctamente, específicamente eliminando números (1,200,345, etc.) de las fechas, que es la pregunta original. Aquí hay un método poco ortodoxo en el que podría pensar y parece funcionar. Indique si hay casos en los que fallará.

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

Esta es la línea para eliminar los números. Por lo tanto, toda la función podría verse así:

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"));

peekolo
fuente
1
console.log("hello 1 ", isDate("hello 1 "));vuelve verdadero
John
¡tienes razón! ¿tienes una solución? ¡Hasta ahora creo que ninguna de las respuestas aquí realmente aborda la pregunta de manera apropiada!
peekolo
"100%", un porcentaje, devuelve verdadero
toddmo
0

¿está bien verificar que una función relacionada con la fecha esté disponible para que el objeto encuentre si es un objeto de fecha o no?

me gusta

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

Así es como termino haciéndolo. Esto no cubrirá todos los formatos. Tienes que ajustar en consecuencia. Tengo control sobre el formato, así que funciona para mí.

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;
            }
        }
kheya
fuente
-1

Ok, esta es una vieja pregunta, pero encontré otra solución mientras comprobaba las soluciones aquí. Para mí, funciona para verificar si la función getTime () está presente en el objeto de fecha:

const checkDate = new Date(dateString);

if (typeof checkDate.getTime !== 'function') {
  return;
}
m.steini
fuente
-1

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

document.getElementById('r2').innerHTML = dayjs('2/6/20').isValid()
<script src="https://unpkg.com/[email protected]/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 biblioteca ligera está lista para ti: Day.js

No hay llave
fuente
1
Esto es básicamente publicidad en StackOverflow, abstenerse de hacerlo.
c4sh
-4
SimpleDateFormat sdf = new SimpleDateFormat(dateFromat);
sdf.setLenient(false);

Por defecto, esto se establece en VERDADERO. Entonces, incluso las cadenas de formato incorrecto devuelven buenos valores.

Lo he usado algo como esto:

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");
  }
Anupam Mahapatra
fuente
55
... javascript ?!
artparks
-5

Prueba esto:

if (var date = new Date(yourDateString)) {
    // if you get here then you have a valid date       
}
Andrew Hare
fuente
66
Esto no funciona para mi. Primero, la var en la condición no se analiza, pero si la elimina y prueba algo como esto: if (date = new Date ("basura")) {alert (date); } Incluso si la fecha es basura, la alerta seguirá ejecutándose ya que la función Fecha devolverá "Fecha inválida" (al menos en Firefox), por lo que la condición se evalúa como verdadera. Supongo que si algunos navegadores devuelven nulo en una fecha no válida, entonces funcionaría en esos navegadores. Podría haber inconsistencias en el navegador aquí.
Cloudranger