new Date () працює в Chrome, але не у Firefox


89

Я створюю рядок дати та часу, який виглядає так: 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
Sinan

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

Зараз це працює у Firefox.
Sm Yamashita

Відповіді:


78

Ви не можете створити екземпляр об’єкта дати як завгодно. Це має бути певним чином. Ось кілька валідних прикладів:

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

Від коментаря apsillers :

специфікація EMCAScript вимагає рівно одного формату дати (тобто РРРР-ММ-DDTHH: мм: ss.sssZ), але користувацькі формати дат можуть вільно підтримуватися реалізацією : " Якщо рядок не відповідає цьому формату [визначеному ECMAScript] функція може повернутися до будь-яких специфічних для реалізації евристик або форматів дат, конкретних для реалізації. "Chrome і FF просто мають різні" формати дат для конкретної реалізації ".


3
Я отримав рішення, яке працює у всіх браузерах, включаючи Firefox: stackoverflow.com/a/21984717/586051
Рахул Десай,

7
Щодо того, чому існує ця різниця в браузері: специфікація EMCAScript вимагає рівно одного формату дати (тобто YYYY-MM-DDTHH:mm:ss.sssZ), але користувацькі формати дат можуть вільно підтримуватися реалізацією : " Якщо рядок не відповідає цьому формату [визначеному ECMAScript], функція може повернімось до будь-якої специфічної для реалізації евристики або конкретних форматів дат для реалізації. "Chrome і FF просто мають різні" формати дат для конкретної реалізації ".
apsillers

Один із прикладів формату дати (місяць, що включає "."), Який працює в Chrome, але не у Firefox: 'лютий. 14, 2019 '
codecribblr

23

Це працює у всіх браузерах -

нова дата ('31.01.2001 00:00:00')

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

Формат: РРРР-ММ-ДДТГГ: мм: ss.sss

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


тому що всі ми знаємо, що це міжнародний стандарт. w3.org/International/questions/qa-date-format
таблиці Боббі

6
Отже, ви насправді протестували всі браузери ? І припускаючи, що у вас є, ви також знаєте, що всі браузери в майбутньому також підтримуватимуть цей (нестандартний) формат?
RobG

1
Це працює для мене. Отже, якщо ви вже отримали рядок "2001-1-31 12:00:00", ми можемо просто зробити: new Date (str.replace (/ - / g, '/'));
Jianwu Chen

@JianwuChen Ви навмисно модифікуєте стандартний формат у нестандартний. Не гарна ідея.
JJJ

2
Через 3 роки він не працює на Edge and 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 = нова дата ('28.08.2018 20:02'. замінити (/ - / g, '/')); Це чудово працює для мене в хромі, а також у 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 працюватиме.


0

Насправді, Chrome є більш гнучким для роботи з різними форматами рядків. Навіть якщо ви не зрозуміли його формат рядка, Chrome все одно може успішно перетворити рядок на дату без помилок. Подобається це:

  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

Це те, що працювало для мене 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.

Щасти...


-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.