Мне нужна функция Javascript, которая с учетом часового пояса возвращает текущее смещение utc.
Например, theFuncIneed('США/Восток') -> 240
Есть идеи?
Спасибо
Мне нужна функция Javascript, которая с учетом часового пояса возвращает текущее смещение utc.
Например, theFuncIneed('США/Восток') -> 240
Есть идеи?
Спасибо
Вообще это невозможно.
US/Eastern
– это идентификатор часового пояса. (На самом деле это псевдоним America/New_York
, который является настоящим идентификатором.)
240
– это смещение часового пояса. Чаще пишется как -04:00
(переверните знак, разделите на 60).
Восточный часовой пояс США состоит из восточного стандартного времени со смещением -05:00
и восточного летнего времени со смещением -04:00
.
Таким образом, совсем неточно говорить US/Eastern
= 240. Пожалуйста, прочитайте вики тега часового пояса, особенно раздел под названием "Время Зона != Смещение".
Теперь вы запросили текущее смещение, что возможно. Если вы предоставите ссылку на дату + время, вы можете решить эту проблему.
Для местного часового пояса компьютера, на котором выполняется код javascript, это встроено в .getTimeZoneOffset()
из любого экземпляра объекта Date
.
Но если вы хотите использовать его для конкретного часового пояса, вам нужно будет использовать одну из библиотек, которые я перечислил. здесь.
UTC - localTime
, выраженное в минутах. . Поэтому я думаю, что на форуме javascript разумно писать +240
там, где в противном случае можно было бы использовать -04:00
.
- person RobG; 21.12.2013
.getTimeZoneOffset()
должно быть .getTimezoneOffset()
без заглавной буквы Z
- person Graham Walters; 21.08.2015
Следующая функция может использоваться для возврата смещения UTC с учетом часового пояса:
const getTimezoneOffset = (timeZone, date = new Date()) => {
const tz = date.toLocaleString("en", {timeZone, timeStyle: "long"}).split(" ").slice(-1)[0];
const dateString = date.toString();
const offset = Date.parse(`${dateString} UTC`) - Date.parse(`${dateString} ${tz}`);
// return UTC offset in millis
return offset;
}
Его можно использовать как:
const offset = getTimezoneOffset("Europe/London");
console.log(offset);
// expected output => 3600000
Date.parse(`${dateString} ${tz}`) - Date.parse(`${dateString} UTC`);
. В противном случае он не будет соответствовать встроенному Date.prototype.getTimezoneOffset
.
- person fgblomqvist; 30.09.2020
"Europe/London"
должен быть 0
- person Avraham; 04.03.2021
timeZoneName
- person dude; 07.07.2021
NaN
для меня.
- person dude; 07.07.2021
Вы можете сделать это, используя moment.js
moment.tz('имя часового пояса').utcOffset()
Хотя это связано с использованием moment-timezone.js
Сегодня это стало возможным благодаря Международному API. :
Реализация Intl
основана на icu4c. Если вы покопаетесь в исходном коде, вы обнаружите, что название часового пояса различается в зависимости от локали, например:
for (const locale of ["ja", "en", "fr"]) {
const timeZoneName = Intl.DateTimeFormat(locale, {
timeZoneName: "short",
timeZone: "Asia/Tokyo",
})
.formatToParts()
.find((i) => i.type === "timeZoneName").value;
console.log(timeZoneName);
}
К счастью, существует локаль Interlingua (тег языка – ia
), в которой используются те же шаблон (например, GMT+11:00
) для названий часовых поясов.
Фрагмент ниже может удовлетворить ваши потребности:
const getOffset = (timeZone) => {
const timeZoneName = Intl.DateTimeFormat("ia", {
timeZoneName: "short",
timeZone,
})
.formatToParts()
.find((i) => i.type === "timeZoneName").value;
const offset = timeZoneName.slice(3);
if (!offset) return 0;
const matchData = offset.match(/([+-])(\d+)(?::(\d+))?/);
if (!matchData) throw `cannot parse timezone name: ${timeZoneName}`;
const [, sign, hour, minute] = matchData;
let result = parseInt(hour) * 60;
if (sign === "+") result *= -1;
if (minute) result += parseInt(minute);
return result;
};
console.log(getOffset("US/Eastern")); // 240
console.log(getOffset("Atlantic/Reykjavik")); // 0
console.log(getOffset("Asia/Tokyo")); // -540
Этот способ может быть немного сложным, но он хорошо работает в моем производственном проекте. Я надеюсь, что это поможет и вам :)
Большое спасибо Борту за указание на опечатку. Я исправил фрагмент.
if (minute) result + parseInt(minute);
есть опечатка. Это должно быть +=
?
- person Bort; 03.11.2020
0
для getOffset("Atlantic/Reykjavik")
, потому что это текущее смещение этого часового пояса относительно UTC. Для getOffset("US/Eastern")
возвращается 240
, а не 0
.
- person kleinfreund; 11.05.2021
0
вместо console.log(getOffset("US/Eastern"));
- person Avraham; 12.05.2021
Intl.DateTimeFormat("ia", { timeZoneName: "short", timeZone: "US/Eastern", }).formatToParts().find((i) => i.type === "timeZoneName").value
? Возможно, что-то, что не начинается с "GMT"
? И если да, запускаете ли вы это в браузере или, возможно, в среде Node.js?
- person kleinfreund; 12.05.2021
timeZoneName
будет MESZ
в Chrome, и это приводит к Cannot parse timezone name
. Ввод: Europe/Zurich
. В файрфоксе работает.
- person dude; 07.07.2021
Ответ @ranjan_purbey приводит к NaN
для меня, а ответ @Weihang Jian вызывает исключение в Chrome (но работает в Firefox).
Поэтому, основываясь на всех ответах, я придумал следующую функцию, которая в основном представляет собой комбинацию обоих ответов, успешно работающих вместе для меня:
const getTimeZoneOffset(timeZone) {
const date = new Date().toLocaleString('en', {timeZone, timeZoneName: 'short'}).split(' ');
const timeZoneName = date[date.length - 1];
const offset = timeZoneName.slice(3);
if (!offset) {
return 0;
}
const matchData = offset.match(/([+-])(\d+)(?::(\d+))?/);
if (!matchData) {
throw new Error(`Cannot parse timezone name: ${timeZoneName}`);
}
const [, sign, hour, minute] = matchData;
let result = parseInt(hour, 10) * 60;
if (sign === '+') {
result *= -1;
}
if (minute) {
result += parseInt(minute, 10);
}
return result;
}
zone()
. - person Barmar   schedule 21.12.2013US/Eastern
– это действительный идентификатор часового пояса IANA. Вы можете найти его внизу списка здесь. - person Matt Johnson-Pint   schedule 21.12.2013US/Eastern
будет распознаваться всеми реализациями. - person Matt Johnson-Pint   schedule 21.12.2013