new Date () está funcionando no Chrome, mas não no Firefox

89

Estou criando uma string de data e hora parecida com esta: 2010-07-15 11:54:21

E com o seguinte código recebo uma data inválida no Firefox, mas funciona bem no Chrome

var todayDateTime = year + '-' + month + '-' + day + ' ' + hour + ':' + minute + ':' + seconds;
var date1 = new Date(todayDateTime);

No firefox date1 está me dando uma data inválida, mas no cromo está funcionando bem, qual seria a causa principal?

Pixeldev
fonte
2
se você quiser brincar com ele de qualquer maneira, vá com datejs.com
Sinan
Nem todas as implementações suportam o formato ECMA-262, portanto, sempre analise as strings manualmente (uma biblioteca pode ajudar, mas provavelmente não é necessária para formatos únicos).
RobG
Funciona com o Firefox agora.
Sm Yamashita

Respostas:

78

Você não pode instanciar um objeto de data da maneira que quiser. Tem que ser de uma maneira específica. Aqui estão alguns exemplos válidos:

new Date() // current date and time
new Date(milliseconds) //milliseconds since 1970/01/01
new Date(dateString)
new Date(year, month, day, hours, minutes, seconds, milliseconds)

ou

d1 = new Date("October 13, 1975 11:13:00")
d2 = new Date(79,5,24)
d3 = new Date(79,5,24,11,33,0)

O Chrome deve ser apenas mais flexível.

Fonte: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date

Do comentário de apsillers :

a especificação EMCAScript requer exatamente um formato de data (ou seja, AAAA-MM-DDTHH: mm: ss.sssZ), mas os formatos de data personalizados podem ser suportados gratuitamente por uma implementação : " Se a string não estiver em conformidade com esse formato [definido por ECMAScript] a função pode recorrer a qualquer heurística específica de implementação ou formatos de data específicos de implementação. "Chrome e FF simplesmente têm diferentes" formatos de data específicos de implementação. "

Chris Laplante
fonte
3
Eu tenho uma solução que funciona em todos os navegadores, incluindo Firefox: stackoverflow.com/a/21984717/586051
Rahul Desai
7
Por que essa diferença de navegador existe: a especificação EMCAScript requer exatamente um formato de data (ou seja, YYYY-MM-DDTHH:mm:ss.sssZ) , mas os formatos de data personalizados podem ser suportados gratuitamente por uma implementação : " Se a String não estiver em conformidade com esse formato [definido pelo ECMAScript], a função pode recorrer a qualquer heurística específica de implementação ou formatos de data específicos de implementação. "Chrome e FF simplesmente têm diferentes" formatos de data específicos de implementação. "
apsillers
Um exemplo de formato de data (mês que inclui um ".") Que funciona no Chrome, mas não no Firefox: 'Fev. 14, 2019 '
codescribblr
23

Isso funciona em todos os navegadores -

nova data ('2001/01/31 12:00:00 AM')

new Date('2001-01-31 12:00:00')

Formato: AAAA-MM-DDTHH: mm: ss.sss

Detalhes: http://www.ecma-international.org/ecma-262/5.1/#sec-15.9.1.15

Tahin Rahman
fonte
porque todos nós sabemos que é um padrão internacional. w3.org/International/questions/qa-date-format
Bobby Tables
6
Então você realmente testou todos os navegadores ? E presumindo que sim, você também sabe que todos os navegadores no futuro também oferecerão suporte a esse formato (não padrão)?
RobG
1
Isso funciona para mim. Portanto, se você já obteve uma string de '2001-1-31 12:00:00', podemos simplesmente fazer: new Date (str.replace (/ - / g, '/'));
Jianwu Chen
@JianwuChen Você está modificando deliberadamente um formato padrão para fora do padrão. Não é uma boa ideia.
JJJ de
2
Depois de 3 anos depois, ele não está mais funcionando no Edge e no Window Safari.
Mg Thar
13

Opção 1 :

Suponha que sua sequência de tempo tenha um formato parecido com este:

'2016-03-10 16:00:00.0'

Nesse caso, você poderia fazer um regex simples para convertê-lo em ISO 8601:

'2016-03-10 16:00:00.0'.replace(/ /g,'T')

Isso produziria a seguinte saída:

'2016-03-10T16:00:00.0'

Este é o formato datetime padrão e, portanto, compatível com todos os navegadores:

document.body.innerHTML = new Date('2016-03-10T16:00:00.0') // THIS IS SAFE TO USE

Opção 2 :

Suponha que sua sequência de tempo tenha um formato parecido com este:

'02-24-2015 09:22:21 PM'

Aqui, você pode fazer o seguinte regex:

'02-24-2015 09:22:21 PM'.replace(/-/g,'/');

Isso também produz um formato compatível com todos os navegadores:

document.body.innerHTML = new Date('02/24/2015 09:22:21 PM') // THIS IS SAFE TO USE

Opção 3:

Suponha que você tenha uma sequência de tempo que não seja fácil de ajustar a um dos padrões bem suportados.

Nesse caso, é melhor apenas dividir sua sequência de tempo em partes diferentes e usá-las como parâmetros individuais para Date:

document.body.innerHTML = new Date(2016, 2, 26, 3, 24, 0); // THIS IS SAFE TO USE

John Slegers
fonte
1
var d = new Date ('2017-08-28 20:02 PM'.replace (/ - / g,' / ')); Isso funciona perfeitamente para mim no Chrome e também no Mozilla.
Rahul Mankar
13

Isso funciona na maioria dos navegadores também

new Date('2001/01/31 12:00:00')

Esse é o formato de

"yyyy/MM/dd HH:mm:ss"
Alvis
fonte
3
Não há garantia de que o formato funcionará em qualquer navegador, muito menos em "todos".
RobG
Você está certo sobre isso, a resposta é baseada na minha experiência.
Alvis
8

Se você ainda deseja criar a data usando travessões, pode usar este formato:

var date = new Date('2013-08-31T17:00:00Z')

Mas tenha em mente que ele cria o tempo de acordo com o UTC. Ou seja, se você mora no fuso horário GMT + 3 (3 horas antes do GMT), ele adicionará essa diferença de fuso horário ao horário. Portanto, o exemplo acima terá este valor, se GMT + 3 (observe que é hora 20:00 e não 17:00):

Sat Aug 31 2013 20:00:00 GMT+0300 (FLE Standard Time)

Certifique-se de adicionar a letra 'Z' no final, porque caso contrário, o Chrome e o Firefox irão analisar a string de forma diferente (um adicionará a diferença de tempo e o outro não).

Gabrielius
fonte
1
Sim, o chrome e o firefox se comportam de maneira diferente se você não fornecer um fuso horário. E, por interesse, eu acho que o Firefox faz isso errado. Deve assumir GMT se o fuso horário estiver ausente. O Chrome sim, o firefox não. ecma-international.org/ecma-262/5.1/#sec-15.9.1.15
Julian Jelfs
@ JulianJelfs— " Deve assumir GMT se o fuso horário estiver ausente ", apenas para a data (ao contrário do ISO 8601). Para strings de data e hora, deve assumir local (consistente com ISO 8601). Mas, em qualquer caso, a análise manual é o único caminho seguro a seguir.
RobG de
5

Eu estava tendo um problema semelhante no Firefox e no Safari ao trabalhar com o AngularJS. Por exemplo, se uma data retornada do Angular for assim:

2014-06-02 10:28:00

usando este código:

new Date('2014-06-02 10:28:00').toISOString();

retorna um erro de data inválida no Firefox e Safari. No entanto, no Chrome funciona bem. Como outra resposta afirmou, o Chrome é provavelmente apenas mais flexível com a análise de strings de data.

Meu objetivo final era formatar a data de uma certa maneira. Encontrei uma excelente biblioteca que lida com o problema de compatibilidade entre navegadores e o problema de formatação de data. A biblioteca é chamada moment.js .

Usando esta biblioteca, o código a seguir funciona corretamente em todos os navegadores que testei:

moment('2014-06-02 10:28:00').format('MMM d YY')

Se você deseja incluir esta biblioteca extra em seu aplicativo, você pode construir mais facilmente sua string de data, evitando possíveis problemas de compatibilidade do navegador. Como bônus, você terá uma boa maneira de formatar, adicionar, subtrair, etc. datas, se necessário.

Instantâneo
fonte
Você deve sempre passar o formato para moment.js ao analisar strings, caso contrário, ele apenas adivinha até encontrar uma que crie uma data válida.
RobG
4

Isso deve funcionar para você:

var date1 = new Date(year, month, day, hour, minute, seconds);

Tive que criar uma data a partir de uma string, então fiz assim:

var d = '2013-07-20 16:57:27';
var date1 = new Date(d.substr(0, 4), d.substr(5, 2), d.substr(8, 2), d.substr(11, 2), d.substr(14, 2), d.substr(17, 2));

Lembre-se de que os meses em javascript vão de 0 a 11, então você deve reduzir o valor do mês em 1, assim:

var d = '2013-07-20 16:57:27';
var date1 = new Date(d.substr(0, 4), d.substr(5, 2) - 1, d.substr(8, 2), d.substr(11, 2), d.substr(14, 2), d.substr(17, 2));
Bartek Kosa
fonte
2

Solução simples, que funciona com todos os navegadores,

var StringDate = "24-11-2017"   
var DateVar = StringDate.split("-");
var DateVal = new Date(DateVar[1] + "/" + DateVar[0] + "/" + DateVar[2]);
alert(DateVal);
XORG_99
fonte
1

Uma situação que encontrei foi ao lidar com milissegundos. O FF e o IE não analisarão essa string de data corretamente ao tentar criar uma nova data. "2014/11/24 17:38:20.177Z" Eles não sabem como lidar .177Z. No entanto, o Chrome funcionará.

bjo
fonte
0

Na verdade, o Chrome é mais flexível para lidar com diferentes formatos de string. Mesmo que você não descubra seu formato de String, o Chrome ainda pode converter String em Data sem erros. Como isso:

  var outputDate = new Date(Date.parse(inputString));

Mas para Firefox e Safari, as coisas se tornam mais complexas. Na verdade, no documento do Firefox, já diz: ( https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/parse )

Uma string representando uma data RFC2822 ou ISO 8601 (outros formatos podem ser usados, mas os resultados podem ser inesperados).

Portanto, quando quiser usar Date.parse no Firefox e Safari, você deve ter cuidado. Para mim, uso um método de truque para lidar com isso. (Nota: pode não ser sempre correto para todos os casos)

if (input.indexOf("UTC") != -1) {
  var tempInput = inputString.substr(0, 10) + "T" + inputString.substr(11, 8) + "Z";
  date = new Date(Date.parse(tempInput));
}

Aqui, ele converte 2013-08-08 11:52:18 UTC para 2013-08-08T11: 52: 18Z primeiro e, em seguida, seu formato é adequado para palavras no documento do Firefox. Neste momento, Date.parse estará sempre correto em qualquer navegador.

Haimei
fonte
0

Isso é o que funcionou para mim em Firefoxe Chrome:

// The format is 'year-month-date hr:mins:seconds.milliseconds'
const d = new Date('2020-1-4 12:00:00.999') 
// we use the `.` separator between seconds and milliseconds.

Boa sorte...

Aakash
fonte
-1

No Firefox, qualquer Date inválido é retornado como um objeto Date como Date 1899-11-29T19:00:00.000Z, portanto, verifique se o navegador é Firefox e obtenha o objeto Date da string "1899-11-29T19:00:00.000Z".getDate(). Finalmente compare com a data.

Shahrukh Azeem
fonte
Isso não explica a causa do problema, mas sim qual seria o resultado do problema.
Rytis,
-1

Usei o seguinte formato de data e está funcionando em todos os navegadores.

var target_date = new Date("Jul 17, 2015 16:55:22").getTime();

var days, hours, minutes, seconds;

var countdown = document.getElementById("countdown");

remaining = setInterval(function () {

    var current_date = new Date().getTime();
    var seconds_left = (target_date - current_date) / 1000;
    days = parseInt(seconds_left / 86400);
    seconds_left = seconds_left % 86400;
    hours = parseInt(seconds_left / 3600);
    seconds_left = seconds_left % 3600;
    minutes = parseInt(seconds_left / 60);
    seconds = parseInt(seconds_left % 60);
    countdown.innerHTML = "<b>"+days + " day, " + hours + " hour, "
        + minutes + " minute, " + seconds + " second.</b>";  
}, 1000);
umesh
fonte