Caso um:
new Date(Date.parse("Jul 8, 2005"));
Resultado:
Sexta, 08 de julho de 2005 00:00:00 GMT-0700 (PST)
Caso dois:
new Date(Date.parse("2005-07-08"));
Resultado:
Qui Jul 07 2005 17:00:00 GMT-0700 (PST)
Por que a segunda análise está incorreta?
javascript
date
user121196
fonte
fonte
NaN
no Firefox, descobri que a maioria dos outros navegadores (e o Node.js) analisam uma data sem um dia, como "abril de 2014" como 1º de abril de 2014, mas o Firefox retorna NaN. Você deve passar uma data adequada.Respostas:
Até a especificação da 5ª edição, o
Date.parse
método era completamente dependente da implementação (new Date(string)
é equivalente a,Date.parse(string)
exceto que o último retorna um número em vez de aDate
). Na 5ª edição, o requisito foi adicionado para oferecer suporte a uma ISO-8601 simplificada (e um pouco incorreta) (também consulte O que são seqüências de data e hora válidas em JavaScript? ). Mas, além disso, não havia nenhum requisito para o queDate.parse
/new Date(string)
deveria aceitar, exceto que eles tinham que aceitar qualquerDate#toString
saída (sem dizer o que era).A partir do ECMAScript 2017 (edição 8), as implementações eram necessárias para analisar sua saída para
Date#toString
eDate#toUTCString
, mas o formato dessas cadeias não era especificado.A partir do ECMAScript 2019 (edição 9), o formato para
Date#toString
eDate#toUTCString
foi especificado como (respectivamente):por exemplo, ter 10 de julho de 2018 18:39:58 GMT + 0530 (IST)
. Terça-feira, 10 de julho de 2018 13:09:58 GMT
fornecendo mais 2 formatos que
Date.parse
devem analisar de maneira confiável em novas implementações (observando que o suporte não é onipresente e as implementações não compatíveis permanecerão em uso por algum tempo).Eu recomendaria que as seqüências de datas sejam analisadas manualmente e o construtor Date seja usado com argumentos de ano, mês e dia para evitar ambiguidade:
fonte
Date.parse
não estava se comportando com formatos de data do Reino Unido, por algum motivo eu não poderia trabalhar para forareturn new Date(parts[0], parts[1] - 1, parts[2], parts[3], parts[4], parts[5]);
Funciona perfeitamente, obrigado!Durante uma experiência recente ao escrever um intérprete de JS, lutei bastante com o funcionamento interno das datas da ECMA / JS. Então, acho que vou jogar meus 2 centavos aqui. Esperamos que o compartilhamento dessas coisas ajude outras pessoas com qualquer dúvida sobre as diferenças entre os navegadores na maneira como lidam com as datas.
O lado da entrada
Todas as implementações armazenam seus valores de data internamente como números de 64 bits que representam o número de milissegundos (ms) desde 01-01-2009 UTC (GMT é a mesma coisa que UTC). Essa data é a época do ECMAScript que também é usada por outros idiomas, como sistemas Java e POSIX, como o UNIX. As datas que ocorrem após a época são números positivos e as datas anteriores são negativas.
O código a seguir é interpretado como a mesma data em todos os navegadores atuais, mas com o deslocamento do fuso horário local:
No meu fuso horário (EST, que é -05: 00), o resultado é 18000000 porque é quantos ms há em 5 horas (são apenas 4 horas durante os meses de verão). O valor será diferente em diferentes fusos horários. Esse comportamento é especificado no ECMA-262 para que todos os navegadores façam o mesmo.
Embora exista alguma variação nos formatos de sequência de entrada que os principais navegadores analisarão como datas, eles essencialmente os interpretam da mesma forma no que diz respeito a fusos horários e horário de verão, embora a análise seja amplamente dependente da implementação.
No entanto, o formato ISO 8601 é diferente. É um dos dois únicos formatos descritos no ECMAScript 2015 (ed 6) especificamente que deve ser analisado da mesma maneira por todas as implementações (o outro é o formato especificado para Date.prototype.toString ).
Mas, mesmo para as cadeias de formato ISO 8601, algumas implementações estão erradas. Aqui está uma saída de comparação do Chrome e Firefox quando esta resposta foi originalmente escrita para 1/1/1970 (a época) na minha máquina usando cadeias de formato ISO 8601 que devem ser analisadas exatamente para o mesmo valor em todas as implementações:
Essa diferença foi corrigida a partir de 2020, mas existem outras peculiaridades entre os navegadores ao analisar as cadeias de formato ISO 8601.
Mas piora. Uma peculiaridade do ECMA-262 é que o formato somente data ISO 8601 (AAAA-MM-DD) deve ser analisado como UTC, enquanto o ISO 8601 exige que ele seja analisado como local. Aqui está a saída do FF com os formatos de data ISO longo e curto sem especificador de fuso horário.
Portanto, o primeiro é analisado como local porque é a data e hora da ISO 8601 sem fuso horário e o segundo é analisado como UTC porque é apenas a data da ISO 8601.
Portanto, para responder diretamente à pergunta original, o
"YYYY-MM-DD"
ECMA-262 exige que seja interpretado como UTC, enquanto o outro é interpretado como local. É por isso:Isso não produz resultados equivalentes:
Isto faz:
A linha inferior é esta para analisar seqüências de datas. A ÚNICA string ISO 8601 que você pode analisar com segurança nos navegadores é o formato longo com um deslocamento (± HH: mm ou "Z"). Se você fizer isso, poderá ir e voltar com segurança entre o horário local e o UTC.
Isso funciona nos navegadores (após o IE9):
A maioria dos navegadores atuais trata os outros formatos de entrada igualmente, incluindo os usados com frequência '1/1/1970' (M / D / AAAA) e '1/1/1970 00:00:00 AM' (M / D / AAAA hh : mm: ss ap) formatos. Todos os seguintes formatos (exceto o último) são tratados como entrada da hora local em todos os navegadores. A saída desse código é a mesma em todos os navegadores no meu fuso horário. O último é tratado como -05: 00, independentemente do fuso horário do host, porque o deslocamento é definido no registro de data e hora:
No entanto, como a análise até dos formatos especificados no ECMA-262 não é consistente, é recomendável nunca confiar no analisador interno e sempre analisar manualmente as seqüências de caracteres, digamos, usando uma biblioteca e fornecendo o formato ao analisador.
Por exemplo, em moment.js você pode escrever:
O lado da saída
No lado da saída, todos os navegadores convertem os fusos horários da mesma maneira, mas manipulam os formatos de sequência de maneira diferente. Aqui estão as
toString
funções e o que elas produzem. Observe que as funçõestoUTCString
etoISOString
saem às 5:00 da manhã na minha máquina. Além disso, o nome do fuso horário pode ser uma abreviação e pode ser diferente em diferentes implementações.Converte do UTC para o horário local antes de imprimir
Imprime diretamente a hora UTC armazenada
Normalmente não uso o formato ISO para entrada de string. A única vez que usar esse formato é benéfico para mim é quando as datas precisam ser classificadas como cadeias. O formato ISO pode ser classificado como está, enquanto os outros não. Se você precisar ter compatibilidade entre navegadores, especifique o fuso horário ou use um formato de sequência compatível.
O código
new Date('12/4/2013').toString()
passa pela seguinte pseudo-transformação interna:Eu espero que a resposta tenha ajudado.
fonte
Existe algum método para a loucura. Como regra geral, se um navegador puder interpretar uma data como uma ISO-8601, será. "08-07-2005" se enquadra neste campo e, portanto, é analisado como UTC. "8 de julho de 2005" não pode e, portanto, é analisado no horário local.
Veja JavaScript e datas, que confusão! para mais.
fonte
Outra solução é criar uma matriz associativa com formato de data e reformatar os dados.
Este método é útil para a data formatada de maneira não convencional.
Um exemplo:
fonte
Use moment.js para analisar datas:
O terceiro argumento determina a análise estrita (disponível a partir do 2.3.0). Sem ele, o moment.js também pode fornecer resultados incorretos.
fonte
De acordo com http://blog.dygraphs.com/2012/03/javascript-and-dates-what-mess.html, o formato "aaaa / mm / dd" resolve os problemas comuns. Ele diz: "Atenha-se a" AAAA / MM / DD "para suas seqüências de datas sempre que possível. É universalmente suportado e sem ambiguidade. Com esse formato, todos os horários são locais". Eu defini testes: http://jsfiddle.net/jlanus/ND2Qg/432/ Este formato: + evita a ambiguidade da ordem do dia e do mês usando a ordenação ymd e um ano com 4 dígitos + evita o problema UTC vs. local não em conformidade com o formato ISO usando slashes + danvk, o cara dos dygraphs , diz que esse formato é bom em todos os navegadores.
fonte
Embora o CMS esteja certo de que a passagem de strings para o método de análise geralmente não é segura, a nova especificação ECMA-262 5th Edition (também conhecida como ES5) na seção 15.9.4.2 sugere que
Date.parse()
realmente deve lidar com datas no formato ISO. A especificação antiga não fez tal afirmação. Obviamente, navegadores antigos e alguns navegadores atuais ainda não fornecem essa funcionalidade ES5.Seu segundo exemplo não está errado. É a data especificada no UTC, conforme implícita
Date.prototype.toISOString()
, mas é representada no seu fuso horário local.fonte
Essa biblioteca de análise de data leve deve resolver todos os problemas semelhantes. Gosto da biblioteca porque é muito fácil estender. Também é possível identificá-lo (não muito direto, mas não tão difícil).
Exemplo de análise:
E formatar de volta para string (você notará que ambos os casos dão exatamente o mesmo resultado):
fonte
Aqui está um trecho curto e flexível para converter uma sequência de data / hora de maneira segura para vários navegadores, conforme o nicel detalhado por @ drankin2112.
Seu navegador deve fornecer o mesmo resultado de carimbo de data / hora que
Date.parse
:fonte
Ambos estão corretos, mas estão sendo interpretados como datas com dois fusos horários diferentes. Então você comparou maçãs e laranjas:
Eu removi a
Date.parse()
chamada, pois ela é usada automaticamente em um argumento de string. Também comparei as datas usando o formato ISO8601 para que você pudesse comparar visualmente as datas entre as datas locais e as datas UTC. Os horários são separados por 7 horas, que é a diferença de fuso horário e por que seus testes mostraram duas datas diferentes.A outra maneira de criar essas mesmas datas locais / UTC seria:
Mas eu ainda recomendo o Moment.js, que é tão simples quanto poderoso :
fonte
A resposta aceita do CMS está correta, acabei de adicionar alguns recursos:
fonte