#javascript #timezone #momentjs
#javascript #Часовой пояс #momentjs
Вопрос:
Я больше дня ломал голову над этим, углубился в исходный код, и, похоже, это проблема с потрясающим javascript moment.tz библиотека:
Всякий раз, когда я передаю идентификатор часового пояса «Etc / GMT time-value«, moment.tz возвращаемый объект возвращается с тем, что я считаю значением формата («Z»), поскольку оно умножается на -1.
Пример:
var pacificTime = moment.tz("2016-09-29 21:00:00","America/Los_Angeles");
pacificTime.format("YYYY-MM-DD HH:mm:ss Z z");
вывод: «2016-09-29 21:00:00 -07:00 ФДТ»
Здесь все так, как и ожидалось.
Теперь, используя тот же часовой пояс (GMT-7):
var GMT_minus_7 = moment.tz("2016-09-29 21:00:00","Etc/GMT-7");
GMT_minus_7.format("YYYY-MM-DD HH:mm:ss Z z");
вывод: «2016-09-29 21:00:00 07:00 GMT-7″
Значение, выделенное жирным шрифтом, всегда является отрицательным значением того, что, по моему мнению, должно быть: передача «Etc / GMT 5» возвращает значение «-5:00».
Это вызывает у меня головную боль, поскольку на веб-странице, с которой я работаю, есть записи с датой / временем, в которых записывается целое значение «GMT offset», которое я просто превращаю в «Etc / GMT» offset_value и передаю в moment.tz чтобы выполнить преобразование часовых поясов. Затем мне нужно выполнить дальнейшие манипуляции со значением (добавление дней, отображение этого значения в формате «Z» и т.д.), Но эта проблема препятствовала дальнейшей работе.
Является ли это дефектом с moment.tz анализ значений часового пояса «Etc / GMT», или я упускаю что-то фундаментальное в форматировании часовых поясов?
Комментарии:
1. Я провел дополнительный тест, и, похоже, это ошибка форматирования в moment.tz ; Я провел следующий тест:
GMT_minus_7.utc().format("YYYY-MM-DD HH:mm:ss Z z")
и получил ответ «2016-09-29 14:00:00 00:00 UTC» Преобразование UTC правильно вычло 7 часов с 21:00 до 14:00. Таким образом, похоже, что форматирование значения «Z» может быть неправильным для этого варианта использования.2. НАПИШИТЕ ваш комментарий — вы позвонили
.utc()
, так что все, что после этого, будет в UTC, то есть00:00
.
Ответ №1:
У идентификаторов в базе данных IANA, например, Etc/GMT-7
намеренно инвертировано смещение. Это часть дизайна этого стиля идентификатора. См. Примечание в Википедии об этом и в самом источнике базы данных tz. (В основном, это связано с необходимостью обратной совместимости со старыми стандартами POSIX в определенных средах.)
Однако в случае Moment.js , вам вообще не нужно их использовать, если вы работаете с фиксированным смещением часового пояса. На самом деле, вам вообще не нужно расширение текущего часового пояса.
// the parseZone method will retain the offset provided
var a = moment.parseZone("2016-09-29 21:00:00 -07:00");
// or, you can set the offset explicitly like this:
var b = moment.utc("2016-09-29 21:00:00").utcOffset("-07:00", true);
// or like this if you prefer:
var c = moment.utc("2016-09-29 21:00:00").utcOffset(-7, true);
Для b
и c
обратите внимание, что true
параметр необходим для сохранения заданного местного времени. Также обратите внимание, что я использую moment.utc(...)
для первоначального анализа строки. Это также будет работать с just moment(...)
, но тогда возможно, что переход на летнее время в местном часовом поясе может повлиять на промежуточное значение.
Кроме того, убедитесь, что вы понимаете, что America/Los_Angeles
он чередуется между -8 и -7 в зависимости от того, действует летнее время или нет. Вот почему вам понадобится moment-timezone для предоставления правил, когда переключаться между смещениями.
Комментарии:
1. Потрясающе! Большое вам спасибо!