moment.tz проблема с установкой часового пояса «Etc / GMT [ |-] HH: MM»

#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. Потрясающе! Большое вам спасибо!