new Date () работает в Chrome, но не в Firefox


93

Я создаю строку даты и времени, которая выглядит так: 2010-07-15 11:54:21

И со следующим кодом я получаю недопустимую дату в Firefox, но отлично работает в Chrome

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

В firefox date1 дает мне недопустимую дату, но в chrome он работает нормально, в чем будет основная причина?


2
если вы хотите поиграть с ним любым способом, перейдите на datejs.com
Синан

Не все реализации поддерживают формат в ECMA-262, поэтому всегда анализируйте строки вручную (библиотека может помочь, но, вероятно, не нужна для отдельных форматов).
RobG

Теперь он работает в Firefox.
Sm Yamashita

Ответы:


80

Вы не можете создать экземпляр объекта даты как хотите. Это должно быть определенным образом. Вот несколько действенных примеров:

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)

или

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

Просто Chrome должен быть более гибким.

Источник: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date

Из комментария апсиллера :

спецификация EMCAScript требует ровно один формат даты (например, ГГГГ-ММ-ДДТЧЧ: мм: сс.сссZ), но пользовательские форматы даты могут свободно поддерживаться реализацией : « Если строка не соответствует этому [определенному в ECMAScript] формате функция может вернуться к любой эвристике, зависящей от реализации, или к формату даты, зависящему от реализации. «Chrome и FF просто имеют разные« форматы даты, зависящие от реализации ».


4
У меня есть решение, которое работает во всех браузерах, включая Firefox: stackoverflow.com/a/21984717/586051
Рахул Десаи,

7
Относительно того, почему существует это различие между браузерами: спецификация EMCAScript требует только одного формата даты (т. Е. YYYY-MM-DDTHH:mm:ss.sssZ), Но пользовательские форматы даты могут свободно поддерживаться реализацией : « Если строка не соответствует этому [определенному в ECMAScript] формате, функция может вернуться к любым эвристикам, зависящим от реализации, или форматам даты, зависящим от реализации. «Chrome и FF просто имеют разные« форматы даты, зависящие от реализации ».
apsillers

Один пример формата даты (месяц, который включает "."), Который работает в Chrome, но не в Firefox: 'Feb. 14, 2019 '
codecribblr

Это сработало для меня только в firefox, если я добавил 'миллисекунды, в Date('milliseconds')противном случае я получил сообщение об ошибке, в котором говорилось, что миллисекунды не были определены, но, по крайней мере, это сработало, когда многие другие попытки не удались. В Chrome все еще кажется счастливым.
Стив

24

Это работает во всех браузерах -

новая дата ('2001/01/31 12:00:00 AM')

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

Формат: ГГГГ-ММ-ДДТЧЧ: мм: сс.ссс

Подробности: http://www.ecma-international.org/ecma-262/5.1/#sec-15.9.1.15


потому что все мы знаем, что это международный стандарт. w3.org/International/questions/qa-date-format
Bobby Tables

6
Итак, вы действительно протестировали все браузеры ? И если предположить, что у вас есть, вы также знаете, что все браузеры в будущем также будут поддерживать этот (нестандартный) формат?
RobG

1
У меня это работает. Итак, если вы уже получили строку «2001-1-31 12:00:00», мы можем просто сделать: new Date (str.replace (/ - / g, '/'));
Jianwu Chen

@JianwuChen Вы намеренно изменяете стандартный формат на нестандартный. Не хорошая идея.
JJJ

2
Спустя 3 года он не работает в Edge и Window Safari.
Mg Thar

13

Опция 1 :

Предположим, ваша временная строка имеет формат, который выглядит следующим образом:

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

В этом случае вы можете сделать простое регулярное выражение, чтобы преобразовать его в ISO 8601:

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

Это даст следующий результат:

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

Это стандартный формат даты и времени, который поддерживается всеми браузерами:

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

Вариант 2:

Предположим, ваша временная строка имеет формат, который выглядит следующим образом:

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

Здесь вы можете сделать следующее регулярное выражение:

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

Это тоже дает формат, поддерживаемый всеми браузерами:

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

Вариант 3:

Предположим, у вас есть временная строка, которую нелегко приспособить к одному из хорошо поддерживаемых стандартов.

В этом случае лучше всего просто разделить временную строку на разные части и использовать их как отдельные параметры для Date:

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


1
var d = new Date ('2017-08-28 20:02 PM'.replace (/ - / g,' / ')); У меня это отлично работает и в Chrome, и в Mozilla.
Рахул

13

Это работает и в большинстве браузеров.

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

Это формат

"yyyy/MM/dd HH:mm:ss"

3
Нет никакой гарантии, что формат будет работать в любом браузере, не говоря уже о «всех».
RobG

Вы правы, ответ основан на моем опыте.
Алвис

8

Если вы все же хотите создать дату с помощью тире, вы можете использовать этот формат:

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

Но имейте в виду, что он создает время по UTC. Это означает, что если вы живете в часовом поясе GMT ​​+ 3 (на 3 часа раньше GMT), он добавит это смещение часового пояса ко времени. Таким образом, в приведенном выше примере будет это значение, если GMT + 3 (обратите внимание, что это 20:00, а не 17:00):

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

Обязательно добавьте букву «Z» в конце, потому что в противном случае Chrome и Firefox будут анализировать строку по-разному (один добавит смещение по времени, а другой нет).


1
Да, Chrome и Firefox ведут себя по-разному, если вы не указываете часовой пояс. И из интереса я думаю, что Firefox делает это неправильно. Он должен предполагать GMT, если часовой пояс отсутствует. Chrome делает, а firefox - нет. ecma-international.org/ecma-262/5.1/#sec-15.9.1.15
Джулиан Джелфс

@ JulianJelfs - « Если часовой пояс отсутствует , он должен предполагать GMT », только для даты (в отличие от ISO 8601). Для строк даты и времени он должен быть локальным (в соответствии с ISO 8601). Но в любом случае ручной синтаксический анализ - единственный безопасный способ.
RobG

5

У меня была аналогичная проблема как в Firefox, так и в Safari при работе с AngularJS. Например, если дата, возвращенная из Angular, выглядела так:

2014-06-02 10:28:00

используя этот код:

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

возвращает ошибку неверной даты в Firefox и Safari. Однако в Chrome все работает нормально. Как указано в другом ответе, Chrome, скорее всего, просто более гибкий с анализом строк даты.

Моя конечная цель состояла в том, чтобы отформатировать дату определенным образом. Я нашел отличную библиотеку, которая решала как проблему кроссбраузерной совместимости, так и проблему форматирования даты. Библиотека называется moment.js .

При использовании этой библиотеки следующий код корректно работает во всех протестированных мной браузерах:

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

Если вы хотите включить эту дополнительную библиотеку в свое приложение, вам будет проще создать строку даты, избегая возможных проблем совместимости с браузером. В качестве бонуса у вас будет хороший способ легко форматировать, добавлять, вычитать и т. Д. Даты, если это необходимо.


Вы всегда должны передавать формат в moment.js при синтаксическом анализе строк, иначе он просто угадывает, пока не найдет тот, который создает действительную дату.
RobG

4

Это должно сработать для вас:

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

Мне пришлось создать дату в виде строки, поэтому я сделал это так:

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

Помните, что месяцы в javascript - от 0 до 11, поэтому вам следует уменьшить значение месяца на 1, например:

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

2

Простое решение, работает со всеми браузерами,

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

1

Одна из ситуаций, с которой я столкнулся, касалась миллисекунд. FF и IE не будут правильно анализировать эту строку даты при попытке создать новую дату. "2014/11/24 17:38:20.177Z" Они не умеют обращаться .177Z. Хотя Chrome будет работать.


1

Вот что у меня сработало Firefoxи 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.

Удачи...


0

Фактически, Chrome более гибок для работы с различными строковыми форматами. Даже если вы не понимаете его формат String, Chrome все равно может успешно преобразовать String в Date без ошибок. Как это:

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

Но для Firefox и Safari все становится сложнее. Фактически, в документе Firefox уже сказано: ( https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/parse )

Строка, представляющая дату RFC2822 или ISO 8601 (могут использоваться другие форматы, но результаты могут быть неожиданными).

Итак, если вы хотите использовать Date.parse в Firefox и Safari, будьте осторожны. Что касается меня, я использую уловку, чтобы справиться с этим. (Примечание: это может быть не всегда верно для всех случаев)

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

Здесь он сначала преобразует 2013-08-08 11:52:18 UTC в 2013-08-08T11: 52: 18Z , а затем его формат соответствует словам в документе Firefox. В настоящее время Date.parse всегда будет работать в любом браузере.


0

Существует спецификация W3C, определяющая возможные строки даты, которые должны анализироваться любым браузером (включая Firefox и Safari):

Year:
   YYYY (e.g., 1997)
Year and month:
   YYYY-MM (e.g., 1997-07)
Complete date:
   YYYY-MM-DD (e.g., 1997-07-16)
Complete date plus hours and minutes:
   YYYY-MM-DDThh:mmTZD (e.g., 1997-07-16T19:20+01:00)
Complete date plus hours, minutes and seconds:
   YYYY-MM-DDThh:mm:ssTZD (e.g., 1997-07-16T19:20:30+01:00)
Complete date plus hours, minutes, seconds and a decimal fraction of a
second
   YYYY-MM-DDThh:mm:ss.sTZD (e.g., 1997-07-16T19:20:30.45+01:00)

где

YYYY = four-digit year
MM   = two-digit month (01=January, etc.)
DD   = two-digit day of month (01 through 31)
hh   = two digits of hour (00 through 23) (am/pm NOT allowed)
mm   = two digits of minute (00 through 59)
ss   = two digits of second (00 through 59)
s    = one or more digits representing a decimal fraction of a second
TZD  = time zone designator (Z or +hh:mm or -hh:mm)

Согласно YYYY-MM-DDThh:mmTZD, пример 2010-07-15 11:54:21должен быть преобразован в 2010-07-15T11:54:21Zили 2010-07-15T11:54:21+02:00(или в любой другой часовой пояс).

Вот краткий пример, показывающий результаты каждого варианта:

const oldDateString = '2010-07-15 11:54:21'
const newDateStringWithoutTZD = '2010-07-15T11:54:21Z'
const newDateStringWithTZD = '2010-07-15T11:54:21+02:00'
document.getElementById('oldDateString').innerHTML = (new Date(oldDateString)).toString()
document.getElementById('newDateStringWithoutTZD').innerHTML = (new Date(newDateStringWithoutTZD)).toString()
document.getElementById('newDateStringWithTZD').innerHTML = (new Date(newDateStringWithTZD)).toString()
div {
  padding: 10px;
}
<div>
  <strong>Old Date String</strong>
  <br>
  <span id="oldDateString"></span>
</div>
<div>
  <strong>New Date String (without Timezone)</strong>
  <br>
  <span id="newDateStringWithoutTZD"></span>
</div>
<div>
  <strong>New Date String (with Timezone)</strong>
  <br>
  <span id="newDateStringWithTZD"></span>
</div>


-1

В Firefox любая недопустимая дата возвращается как объект Date как Date 1899-11-29T19:00:00.000Z, поэтому проверьте, является ли браузер Firefox, а затем получите объект Date строки "1899-11-29T19:00:00.000Z".getDate(). Наконец сравните это с датой.


Это не объясняет причину проблемы, а скорее, каков будет ее исход.
Rytis

-1

Я использовал следующий формат даты, и он работает во всех браузерах.

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);
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.