Javascript - Чому дають неправильні результати Переповнення стека

Випадок перший:

Вихід:

Пт, 08 липня 2005 00:00:00 GMT-0700 (PST)

дають

Випадок другий:

Вихід:

Чт 07 липня 2005 17:00:00 GMT-0700 (PST)

Чому другий розбір неправильний?

11 Відповіді 11

Поки не вийшла специфікація 5-го видання, метод Date.parse повністю залежав від реалізації (нова Date (рядок) еквівалентна Date.parse (рядок), за винятком того, що остання повертає число, а не Date). У специфікації 5-го видання була додана вимога щодо підтримки спрощеного (і дещо неправильного) ISO-8601 (також див. Які дійсні рядки часу та часу в JavaScript?). Але крім цього, не було вимоги щодо того, що Date.parse/new Date (рядок) повинен приймати, крім того, що вони повинні приймати будь-який вивід Date # toString (не кажучи, що це).

Починаючи з ECMAScript 2017 (випуск 8), реалізації були необхідні для синтаксичного аналізу своїх вихідних даних для Date # toString і Date # toUTCString, але формат цих рядків не був вказаний.

Станом на ECMAScript 2019 (видання 9) формат для Date # toString і Date # toUTCString були вказані як (відповідно):

  1. ddd MMM DD YYYY HH: mm: ss ZZ [(назва часового поясу)]
    напр. Вівторок, 10 липня 2018, 18:39:58 GMT + 0530 (IST)
  2. ddd, DD MMM РРРР HH: мм: ss Z
    напр. Вівторок, 10 липня 2018 р., 13:09:58 GMT

надання ще 2 форматів, які Date.parse повинен надійно аналізувати в нових реалізаціях (зазначивши, що підтримка не є всюдисущою, а невідповідні реалізації залишатимуться у користуванні деякий час).

Я б рекомендував аналізувати рядки дат вручну, а конструктор Date використовувати з аргументами рік, місяць та день, щоб уникнути двозначності:

Протягом недавнього досвіду написання перекладача JS я багато боровся з внутрішніми датами ECMA/JS. Отже, я вважаю, що я кину сюди свої 2 центи. Сподіваємось, обмін цими матеріалами допоможе іншим у будь-яких питаннях щодо відмінностей браузерів у тому, як вони обробляють дати.

Усі реалізації зберігають свої значення дати внутрішньо як 64-розрядні числа, які представляють кількість мілісекунд (мс) з 1970-01-01 UTC (GMT - це те саме, що UTC). Ця дата - епоха ECMAScript, яка також використовується іншими мовами, такими як системи Java та POSIX, такими як UNIX. Дати, що трапляються після епохи, є позитивними числами, а дати попередніми - негативними.

Наступний код інтерпретується як однакова дата у всіх поточних браузерах, але з локальним зміщенням часового поясу:

У моєму часовому поясі (EST, що становить -05: 00), результат дорівнює 18000000, тому що це стільки мс за 5 годин (це лише 4 години в перехід на літній час). Значення буде різним у різних часових поясах. Ця поведінка вказана в ECMA-262, тому всі браузери роблять це однаково.

Хоча існують певні розбіжності у форматах вхідних рядків, які основні браузери будуть аналізувати як дати, вони, по суті, інтерпретують їх однаково щодо часових поясів та переходу на літній час, хоча синтаксичний аналіз в основному залежить від реалізації.