Неверная дата в сафари - PullRequest
       36

Неверная дата в сафари

116 голосов
/ 30 ноября 2010
 alert(new Date('2010-11-29'));

chrome, ff не имеет проблем с этим, но сафари выдает «недопустимая дата». Почему?

edit: ок, согласно комментариям ниже, я использовал разбор строк и попробовал это:

alert(new Date('11-29-2010')); //doesn't work in safari
alert(new Date('29-11-2010')); //doesn't work in safari
alert(new Date('2010-29-11')); //doesn't work in safari

edit 22 марта 2018 : Кажется, что люди все еще приземляются здесь - сегодня я бы использовал moment или date-fns и покончил бы с этим. Date-fns также очень безболезненный и легкий.

Ответы [ 15 ]

180 голосов
/ 13 апреля 2011

Для меня реализация новой библиотеки только потому, что Safari не может сделать это правильно, - это слишком много, и регулярное выражение является излишним.Вот это oneliner :

console.log (new Date('2011-04-12'.replace(/-/g, "/")));
136 голосов
/ 30 ноября 2010

Шаблон yyyy-MM-dd не является официально поддерживаемым форматом для конструктора Date.Firefox, кажется, поддерживает это, но не рассчитывайте на то, что другие браузеры будут делать то же самое.

Вот некоторые из поддерживаемых строк, взятых с этого сайта :

  • ММ-дд-гггг
  • гггг / ММ / дд
  • ММ / дд / гггг
  • ММММ дд, гггг
  • МММ дд, гггг

DateJS кажется хорошей библиотекой для анализа нестандартных форматов дат.

Редактировать : только что проверил Стандарт ECMA-262 .Цитирование из раздела 15.9.1.15:

Формат строки даты и времени

ECMAScript определяет формат обмена строк для даты и времени на основе упрощения расширенного формата ISO 8601.Формат выглядит следующим образом: ГГГГ-ММ-ДДЧЧ: мм: сс.сссZ Где следующие поля:

  • ГГГГ - десятичные цифры года в григорианском календаре.
  • "-" (hyphon) встречается буквально дважды в строке.
  • MM - месяц года с 01 (январь) до 12 (декабрь).
  • DD - это день месяца с 01 по 31.
  • Буква «T» появляется буквально в строке, чтобы указать начало элемента времени.
  • ЧЧ - количество полных часов, прошедших с полуночи в виде двух десятичных цифр.
  • ":" (двоеточие) появляется буквально дважды в строке.
  • мм - это количество полных минут с начала часа в виде двух десятичных цифр.
  • ss - количество полных секунд с начала минуты в виде двух десятичных цифр.
  • "."(точка) появляется буквально в строке.
  • sss - это число полных миллисекунд с начала секунды в виде трех десятичных цифр.Оба "."и поле миллисекунд может быть опущено.
  • Z - это смещение часового пояса, указанное как «Z» (для UTC) или «+» или «-», за которым следует выражение времени чч: мм

Этот формат включает в себяФормы только для даты:

  • ГГГГ
  • ГГГГ-ММ
  • ГГГГ-ММ-ДД

Также включает только времяформы с дополнительным смещением часового пояса:

  • THH: мм
  • THH: мм: сс
  • THH: мм: сс.ссс

Также включены «дата-время», которые могут представлять собой любую комбинацию из вышеперечисленного.

Итак, похоже, что YYYY-MM-DD включен в стандарт, но по какой-то причинеSafari не поддерживает его.

Обновление : после просмотра datejs документации , используя его, ваша проблема должна быть решена с помощью кода, подобного этому:

var myDate1 = Date.parseExact("29-11-2010", "dd-MM-yyyy");
var myDate2 = Date.parseExact("11-29-2010", "MM-dd-yyyy");
var myDate3 = Date.parseExact("2010-11-29", "yyyy-MM-dd");
var myDate4 = Date.parseExact("2010-29-11", "yyyy-dd-MM");
29 голосов
/ 17 июля 2017

Я столкнулся с подобной проблемой.Date.Parse("DATESTRING") работал на Chrome (версия 59.0.3071.115), но не на Safari (версия 10.1.1 (11603.2.5))

Safari:

Date.parse("2017-01-22 11:57:00")
NaN

Chrome:

Date.parse("2017-01-22 11:57:00")
1485115020000

Решение, которое работало для меня, заключалось в замене пробела в dateString на "T".(пример: dateString.replace(/ /g,"T"))

Safari:

Date.parse("2017-01-22T11:57:00")
1485086220000

Chrome:

Date.parse("2017-01-22T11:57:00")
1485115020000

Обратите внимание, что ответ от браузера Safari на 8 часов (28800000 мс) меньше, чемв браузере Chrome получен ответ, потому что Safari возвратил ответ в локальном TZ (который на 8 часов позже UTC)* Хром:

Date.parse("2017-01-22T11:57:00Z")
1485086220000
8 голосов
/ 06 июля 2015

Я использую момент, чтобы решить проблему. Например

var startDate = moment('2015-07-06 08:00', 'YYYY-MM-DD HH:mm').toDate();
8 голосов
/ 25 июля 2014

Чтобы решение работало в большинстве браузеров, вам нужно создать объект даты в следующем формате:

(year, month, date, hours, minutes, seconds, ms)

Например:

dateObj = new Date(2014, 6, 25); //UTC time / Months are mapped from 0 to 11
alert(dateObj.getTime()); //gives back timestamp in ms

отлично работает с IE, FF, Chromeи сафари.Даже более старые версии.

IE Dev Center: объект Date (JavaScript)

Сеть разработчиков Mozilla: Date

6 голосов
/ 16 июня 2015

преобразовать строку в дату от даты (вы должны знать часовой пояс сервера)

new Date('2015-06-16 11:00:00'.replace(/\s+/g, 'T').concat('.000+08:00')).getTime()  

, где +08: 00 = часовой пояс с сервера

4 голосов
/ 11 декабря 2014

У меня была такая же проблема. Затем я использовал момент. Js . Проблема исчезла.

При создании момента из строки мы сначала проверяем, соответствует ли строка известным форматам ISO 8601, а затем возвращаемся к новой дате (строке), если известный формат не найден.

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

Для получения согласованных результатов при анализе чего-либо, кроме строк ISO 8601, следует использовать String + Format.

например

var date= moment(String);
3 голосов
/ 30 ноября 2010

Хотя вы можете надеяться, что браузеры будут поддерживать ISO 8601 (или его подмножества только по дате), это не так. Все известные мне браузеры (по крайней мере, в тех регионах США / Англии, которые я использую) способны анализировать ужасный формат US MM/DD/YYYY.

Если у вас уже есть части даты, вы можете вместо этого попробовать Date.UTC () . Если нет, но вы должны использовать формат YYYY-MM-DD, я предлагаю использовать регулярное выражение, чтобы проанализировать известные вам фрагменты, а затем передать их в Date.UTC().

1 голос
/ 01 июня 2018

Лучший способ сделать это - использовать следующий формат:

new Date(year, month, day, hours, minutes, seconds, milliseconds)
var d = new Date(2018, 11, 24, 10, 33, 30, 0);

Это поддерживается во всех браузерах и не доставит вам никаких проблем. Обратите внимание, что месяцы написаны от 0 до 11.

1 голос
/ 14 июля 2017

Как насчет угона Date с фиксированной датой ?Без зависимостей, min + gzip = 280 B

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...