Verifique se uma sequência é um valor de data

207

Qual é uma maneira fácil de verificar se um valor é uma data válida, é permitido qualquer formato de data conhecido.

Por exemplo, eu tenho os valores 10-11-2009, 10/11/2009, 2009-11-10T07:00:00+0000que devem todos ser reconhecidos como valores de data e os valores 200, 10, 350, que não deve ser reconhecido como um valor de data. Qual é a maneira mais simples de verificar isso, se isso é possível? Porque os timestamps também seriam permitidos.

Thizzer
fonte

Respostas:

41

Seria Date.parse()suficiente?

Veja sua página relativa à documentação MDN .

Asmor
fonte
24
Tenha cuidado com isso, pois ele ainda retornará retorno para datas inválidas em fevereiro, por exemplo:
31-02-2013
58
Outro motivo para ter cuidado - os números são analisados ​​como datas. Date.parse("4.3")é 986270400000.
Mogsdad
Tentei mexer nos dois casos de 'cuidado' acima: console.log (Date.parse ("2013-02-31")); console.log (Date.parse ("4.3")); e em ambos os casos (no firefox) ele retornou NaN; portanto, para mim, Date.parse parece OK (estou prevalecendo por traços e comprimento correto antes da análise).
precisa saber é o seguinte
55
Desculpe @Asmor, esta não é uma resposta correta. Date.parse irá analisar qualquer string com um número dentro.
jwerre
11
Date.parse ("Meu nome 8") está chegando como 99662040000, o que está errado. Eu usei isso e agora estou sofrendo.
Rohith
250

Atualização de 2015

É uma pergunta antiga, mas outras perguntas novas, como:

ficar fechado como duplicado deste, então eu acho importante adicionar algumas informações novas aqui. Estou escrevendo porque fiquei com medo de pensar que as pessoas realmente copiam e colam parte do código postado aqui e o usam na produção.

A maioria das respostas aqui quer usar algumas expressões regulares complexas que correspondem formatos só alguns muito específicos e realmente fazê-lo de forma incorrecta (como correspondência janeiro 32, enquanto que não corresponde data ISO real como anunciado - ver demonstração ) ou eles tentam passar nada para aDate construtor e desejo o melhor.

Usando Moment

Como expliquei nesta resposta , atualmente há uma biblioteca disponível para isso: Moment.js

É uma biblioteca para analisar, validar, manipular e exibir datas em JavaScript, que possui uma API muito mais rica que as funções padrão de manipulação de datas em JavaScript.

É 12kB compactado / compactado com gz e funciona no Node.js e em outros locais:

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 o Moment, você pode ser muito específico sobre a verificação de datas válidas. Às vezes, é muito importante adicionar algumas dicas sobre o formato que você espera. Por exemplo, uma data como 22/06/2015 se parece com uma data válida, a menos que você use um formato DD / MM / AAAA. Nesse caso, essa data deve ser rejeitada como inválida. Existem algumas maneiras de dizer ao Moment qual formato você espera, por exemplo:

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

O trueargumento está lá, para que o Moment não tente analisar a entrada se não estiver exatamente de acordo com um dos formatos fornecidos (deve ser um comportamento padrão na minha opinião).

Você pode usar um formato fornecido internamente:

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

E você pode usar vários formatos como uma 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

Veja: DEMO .

Outras bibliotecas

Se você não deseja usar o Moment.js, também existem outras bibliotecas:

Atualização de 2016

Criei o módulo imoment que é como (um subconjunto de) Momento, mas sem surpresas causadas pela mutação de objetos existentes (consulte a documentação para obter mais informações).

Atualização de 2018

Hoje, recomendo usar o Luxon para manipulação de data / hora em vez de Moment, o que (diferentemente do Moment) torna todo objeto imutável, para que não haja surpresas desagradáveis ​​relacionadas à mutação implícita de datas.

Mais informações

Veja também:

Uma série de artigos de Rob Gravelle nas bibliotecas de análise de datas do JavaScript:

Bottom line

É claro que qualquer um pode tentar reinventar a roda, escrever uma expressão regular (mas , na verdade, leia ISO 8601 e RFC 3339 antes de fazê-lo) ou chame construtores de buit-in com dados aleatórios para analisar mensagens de erro como 'Invalid Date'(Tem certeza de que esta mensagem é exatamente o mesmo em todas as plataformas? Em todos os locais? No futuro?) ou você pode usar uma solução testada e usar seu tempo para aprimorá-la, não reinventá-la. Todas as bibliotecas listadas aqui são software livre e de código aberto.

rsp
fonte
4
exatamente como alguém deve usar isso? moment("whatever 123").isValid()retorna true.
krivar
4
@krivar É melhor usá-lo assim: moment("06/22/2015", "DD/MM/YYYY", true).isValid();com o formato de data esperado explicitamente fornecido e com um argumento que truesignifica verificação rigorosa. Atualizei minha resposta com mais informações e melhores exemplos.
RSP
2
Mesmo embora, mas estou validando a entrada do usuário e eu não sei o formato de data esperado ...
Jan Van der Haegen
3
@JanVanderHaegen Se for possível supor que 3/4/5 é uma data válida e o dia 1º de abril de 2015, eu recomendaria adicionar esses formatos (e potencialmente muito mais) a uma lista explícita de formatos suportados. Observe que 3/4/5 que você mencionou é ambíguo sem um formato explícito.
Rsp #
3
Este poderia ser o melhor e mais bem conservado resposta que eu vi no SO
Phil3992
63

Foi assim que resolvi esse problema em um aplicativo no qual estou trabalhando agora:

atualizado com base nos comentários da krillgar:

var isDate = function(date) {
    return (new Date(date) !== "Invalid Date") && !isNaN(new Date(date));
}
Neil Girardi
fonte
5
Eu precisava retornar (nova data (data)). ToString ()! == "Data inválida" para o nó. Observe também que? verdadeiro: falso é redundante. simplesmente retornar a expressão será suficiente aqui.
precisa saber é o seguinte
No IE8, new Date(date)não fornece "Data inválida".
precisa saber é o seguinte
13
Esta não é uma boa resposta. new Date(date) !== "Invalid Date"vai sempre retornar verdadeiro pois a expressão esquerdo retornará um objeto Date com uma TimeValue de NaN , que nunca pode ser ===para uma string. Usando =="funciona" devido à conversão de tipo. Porém, como a análise de strings de data ainda depende em grande parte da implementação, confiando nela para analisar formatos aleatórios que são seriamente falhos.
RobG
4
nova data ("469") resulta em terça-feira 01 de janeiro 469 00:00:00 GMT + 0200 (EET)
Dan Ochiana
3
Isso é semelhante à resposta correta falsamente aceita. isDate('Mac OS X 10.14.2')retorna verdadeiro aqui.
precisa saber é o seguinte
24

new Date(date) === 'Invalid Date'só funciona no Firefox e Chrome. O IE8 (o que eu tenho na minha máquina para fins de teste) fornece NaN.

Como foi afirmado na resposta aceita, Date.parse(date)também funcionará para números. Portanto, para contornar isso, você também pode verificar se não é um número (se é algo que você deseja 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
fonte
2
Sei que alguns anos depois, mas isNannão é uma função; caso incorreto na primeira instância.
Tim Lewis
Não funciona. Se datefor Foostreet 1, sua condição é avaliada como verdadeira.
Fabian Picone
9

Que tal algo como isso? Ele testará se é um objeto Date ou uma string de data:

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 mencionar que isso não testa cadeias de caracteres formatadas em ISO, mas com um pouco mais de trabalho no RegExp você deve ser bom.

jwerre
fonte
7

Nenhuma das respostas aqui aborda a verificação se a data é inválida, como 31 de fevereiro. Esta função aborda isso verificando se o mês retornado é equivalente ao mês original e certificando-se de que um ano válido foi apresentado.

//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 diz Restabelecer Monica
fonte
Como a pergunta não é para verificar se uma string é uma data 'válida', mas apenas verificar se uma string representa um formato de data.
Thizzer
@ Thizzer bom ponto. Eu não me importaria de consertar, mas, ao reler sua pergunta, estou perplexo porque você diz que 10 não deve ser validado, mas que carimbos de data e hora devem ser permitidos.
ykay diz Restabelecer Monica
O xD nem percebeu isso, uma pergunta dos meus dias anteriores com data / hora. Vou tentar editar a pergunta hoje mais tarde.
Thizzer
por que mês-1 e depois mês + 1?
Kapil Raghuwanshi
Datas javascript @KapilRaghuwanshi usar um mês baseado em zero, então você precisa subtrair 1 para criar a data adequada e adicionar 1 para verificar se ele é equivalente ao mês originais
ykay diz Reintegrar Monica
5

Use Expressão regular para validá-la.

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
fonte
4

Ao me referir a todos os comentários acima, cheguei a uma solução.

Isso funciona se o Datepassado estiver no formato ISO ou precisar manipular para outros 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");
}

Você pode jogar aqui no JSFiddle.

Nikhil Zurunge
fonte
1
Essa solução funcionou melhor para mim, pois as strings de data que meu aplicativo suporta são do formato YYYY-MM-DD, portanto, é trivial anexar T00:00:00.000Ze usar essa solução para verificar se há strings válidas.
acelera
para javascript isso está funcionando, mas como usá-lo em texto datilografado.?
Sae
3

Aqui está uma função aprimorada que usa apenas Date.parse():

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

Nota: Date.parse () analisará os números: por exemplo Date.parse(1), retornará uma data. Então aqui verificamos se snão é um número, se é uma data.

A-Sharabiani
fonte
1
isso não funciona, pois o 'teste 2' passa como uma data verdadeira. testado na versão mais recente do chrome
user1751287 7/19
2

Eu faria isso

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

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

Jogue aqui

kiranvj
fonte
2
Isso não funciona no Chrome atual, possivelmente em outros navegadores. Eu mudei a string fornecida EXAMPLE STRING 12345e retorna "Data válida".
1

Aqui está uma versão minimalista.

var isDate = function (date) {
    return!!(function(d){return(d!=='Invalid Date'&&!isNaN(d))})(new Date(date));
}
Mr. Polywhirl
fonte
1
Ainda não funciona para o meu exemplo:isDate("  1")
Tomas
@ Tom Você deve verificar se o valor contém caracteres de espaço em branco antes de determinar se é uma data. Seu problema é um caso especial que precisa ser tratado pela lógica do seu controlador.
Mr. Polywhirl
1
A verificação de caracteres de espaço em branco não deve ser necessária, pois a sequência de 1º de janeiro de 2020 é uma data válida que contém espaço em branco. Seu método não explica isso.
Kirstin Walsh
1

Esta função solicitável funciona perfeitamente, retorna true para data válida. Certifique-se de ligar usando uma data no formato ISO (aaaa-mm-dd ou 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
fonte
1
É bom, mas não responde a pergunta completamente. Especificamente, ele não funciona para '2009-11-10T07: 00: 00 + 0000', um dos exemplos dados.
amadan 29/11
Não acho que isso funcione como deveria validarDate ('2016-12-30T08: 00: 00.000Z') // false
Jose Browne
Independentemente de saber se isso funciona ou não, ele pode ser simplificado comoreturn !isNaN(Date.parse(isoDate)) || isoDate == new Date(isoDate).toISOString().substr(0,10);
Michel Jung
1

Sei que é uma pergunta antiga, mas enfrentei o mesmo problema e vi que nenhuma das respostas funcionava corretamente - eliminando números (1.200.345 etc.) de datas, que é a pergunta original. Aqui está um método pouco ortodoxo em que pude pensar e parece funcionar. Por favor, indique se há casos em que ele falhará.

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

Esta é a linha para eliminar números. Assim, toda a função pode se parecer com:

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
fonte
1
console.log("hello 1 ", isDate("hello 1 "));Retorna true #
John
você está certo! Você tem uma solução? Até agora, acho que nenhuma das respostas aqui realmente abordou a questão adequadamente!
Peekolo
"100%", uma porcentagem, retorna true
toddmo
0

é bom verificar se uma função relacionada à data está disponível para o objeto descobrir se é um objeto de data ou não?

gostar

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

É assim que acabo fazendo isso. Isso não cobrirá todos os formatos. Você tem que ajustar em conformidade. Eu tenho controle sobre o formato, então funciona para mim

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
fonte
-1

Ok, essa é uma pergunta antiga, mas encontrei outra solução enquanto verifica as soluções aqui. Para mim trabalha para verificar se a função getTime () está presente no objeto de data:

const checkDate = new Date(dateString);

if (typeof checkDate.getTime !== 'function') {
  return;
}
m.steini
fonte
-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>

Uma biblioteca leve está pronta para você: Day.js

Nokey
fonte
1
Isso é basicamente publicidade no StackOverflow, evite fazer isso.
c4sh 17/06
-4
SimpleDateFormat sdf = new SimpleDateFormat(dateFromat);
sdf.setLenient(false);

Por padrão, isso é definido como TRUE. Assim, mesmo seqüências de caracteres de formato incorreto retornam bons valores.

Eu usei algo assim:

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
fonte
5
... javascript ?!
artparks
-5

Tente o seguinte:

if (var date = new Date(yourDateString)) {
    // if you get here then you have a valid date       
}
Andrew Hare
fonte
6
Isso não funciona para mim. Primeiro, o var na condição não analisa, mas se você o remover e tentar algo como isto: if (date = new Date ("lixo")) {alert (date); } Mesmo se a data for lixo, o alerta continuará sendo executado, pois a função Date retornará "Data Inválida" (pelo menos no Firefox) para que a condição seja avaliada como verdadeira. Eu acho que se alguns navegadores retornarem nulos na data inválida, funcionaria nesses navegadores. Pode haver inconsistência no navegador aqui.
precisa saber é o seguinte