Date.toString и Date.toLocaleDateString несовместимы в Chrome и Firefox?

Поэтому я хочу отображать дату без особого внимания к времени суток. С датой тоже ничего путного. Я на MacBook Pro.

Если я ввожу числа в конструктор Date, появится следующее изображение.

Я хочу показать, например, 28 апреля 1993 года.

var objDate = new Date(1993, 3, 28),
    dateString = objDate.toLocaleDateString(undefined, {
        weekday: "long",
        year: "numeric",
        month: "long",
        day: "numeric",
        hour: "numeric",
        timeZoneName: 'long'
    });

    console.info(dateString)
    //Chrome Outputs: "Wednesday, April 28, 1993, 12 AM Mountain Daylight Time"
    //Firefox Outpus: "Tuesday, April 27, 1993, 6 PM Mountain Daylight Time"

    let nowDate = new Date(1993, 3, 28);
    console.info(nowDate.toString())
    //Chrome Outputs: "Wed Apr 28 1993 00:00:00 GMT-0600 (Mountain Daylight Time)"
    //Firefox Outputs: "Wed Apr 28 1993 00:00:00 GMT+0000 (UTC)"

    console.info(nowDate.toLocaleString())
    //Chrome Outputs: "4/28/1993, 12:00:00 AM"
    //Firefox Outputs: "4/27/1993, 6:00:00 PM"

Итак, теперь даты показывают и 27-е, и 28-е, хотя я хочу, чтобы отображалось только 28-е.

Но! Если я изменю числа на строковый формат, как в следующем коде. Это все еще непоследовательно.

var objDate = new Date("1993-04-28"),
    dateString = objDate.toLocaleDateString(undefined, {
        weekday: "long",
        year: "numeric",
        month: "long",
        day: "numeric",
        hour: "numeric",
        timeZoneName: 'long'
    });

    console.info(dateString)
    //Chrome Outputs: "Wednesday, April 27, 1993, 12 AM Mountain Daylight Time"
    //Firefox Outpus: "Tuesday, April 27, 1993, 6 PM Mountain Daylight Time"

    let nowDate = new Date("1993-04-28");
    console.info(nowDate.toString())
    //Chrome Outputs: "Wed Apr 27 1993 00:00:00 GMT-0600 (Mountain Daylight Time)"
    //Firefox Outputs: "Wed Apr 28 1993 00:00:00 GMT+0000 (UTC)"

    console.info(nowDate.toLocaleString())
    //Chrome Outputs: "4/27/1993, 12:00:00 AM"
    //Firefox Outputs: "4/27/1993, 6:00:00 PM"

А теперь последний фрагмент кода.

Если я ввожу время дня в строковый формат, например, полдень, он отлично показывает, какой это день.

Обновлено: я только что проверил этот метод в Safari, и он выводит Invalid Date.

var objDate = new Date("1993-04-28 12:00"),
    dateString = objDate.toLocaleDateString(undefined, {
        weekday: "long",
        year: "numeric",
        month: "long",
        day: "numeric",
        hour: "numeric",
        timeZoneName: 'long'
    });

    console.info(dateString)
    //Chrome Outputs: "Wednesday, April 28, 1993, 12 PM Mountain Daylight Time"
    //Firefox Outpus: "Wednesday, April 28, 1993, 6 AM Mountain Daylight Time"

    let nowDate = new Date("1993-04-28");
    console.info(nowDate.toString())
    //Chrome Outputs: "Wed Apr 28 1993 12:00:00 GMT-0600 (Mountain Daylight Time)"
    //Firefox Outputs: "Wed Apr 28 1993 12:00:00 GMT+0000 (UTC)"

    console.info(nowDate.toLocaleString())
    //Chrome Outputs: "4/28/1993, 12:00:00 PM"
    //Firefox Outputs: "4/28/1993, 6:00:00 AM"

Так что вот, в частности, вопросы.

Почему методы с разными входами даты иногда устанавливают другой день? Что браузеры делают по-разному в каждом из перечисленных случаев? Я думал, что каждый из используемых мной методов будет локально, а не в формате UTC.

Обновлено: Возможно, мне просто придется использовать одну из библиотек, чтобы справиться со всеми несоответствиями. Хотя есть ли достаточно маленькая библиотека? Я нашел dayjs, и он выглядит достаточно маленьким.

исходники codepen

Вывод Date.prototype.toString стандартизирован в ECMAScript 2018, однако ранее он зависел от реализации и широко варьировался в разных реализациях. Вывод toLocaleString не стандартизирован и все еще в значительной степени зависит от реализации.

RobG 26.10.2018 00:16
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
1
1
366
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Да, между браузерами много несоответствий. Хуже всего в IE и Safari, где new Date("2018-08-23 18:00:00") не является допустимым форматом даты :) Лучший способ, который я нашел, - это преобразовать его в "зулусское" время и добавить T для времени, например: new Date("2018-08-23T18:00:00Z")

Просто используйте yourDate.replace(" ", "T"); для добавления T, а затем просто добавьте строку Z.

По любому вопросу позвольте мне прокомментировать, спасибо.

2018-08-23 18:00:00 не является форматом даты, как указано в ECMAScript, и поэтому может не работать. Если вообще, вы должны использовать только формат YYYY-MM-DDTHH:mm:ss.sssZ.
str 25.10.2018 21:28

Обратите внимание, что предлагаемые вами изменения изменят строку с представления местной даты и времени на дату и время в формате UTC, что приведет к смещению ее с +14 до -10 часов.

RobG 26.10.2018 00:20
Ответ принят как подходящий

Анализ строк даты зависит от реализации - это означает, что он не согласован в разных браузерах. Некоторые строковые форматы обычно рассматриваются как UTC, а не как локальные. От Документы с датой JavaScript ...

Note: parsing of date strings with the Date constructor (and Date.parse, they are equivalent) is strongly discouraged due to browser differences and inconsistencies. Support for RFC 2822 format strings is by convention only. Support for ISO 8601 formats differs in that date-only strings (e.g. "1970-01-01") are treated as UTC, not local.

Точно так же toString может не создавать строку даты аналогичного формата в браузерах. Из Date.prototype.toString документы (обратите внимание, что ECMAScript 2018 не был полностью реализован во всех браузерах на дату этого ответа) ...

Until ECMAScript 2018 (edition 9), the format of the string returned by Date.prototype.toString was implementation dependent. Therefore it should not be relied upon to be in the specified format.

И toLocaleString, locales и options - это не поддерживается во всех браузерах.

Как вы заметили, существует множество библиотек, таких как Moment.js, которые могут в этом помочь.

Если вы просто пытаетесь взять последовательные входные данные строки даты и переформатировать их для отображения, это может быть не так уж сложно с vanilla js (но сложность во многом зависит от согласованности ваших входных значений). Например:

const formatDate = (date) => {
  const months = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'];
  const [y, m, d] = date.split('-');
  return months[m - 1] + ' ' + d + ', ' + y;
}

const date = formatDate('1993-04-28');
console.info(date);
// April 28, 1993

Другие вопросы по теме