Есть ли надежный способ получить часовой пояс из клиентского браузера? Я видел следующие ссылки, но мне нужно более надежное решение.
Автоматическое определение часового пояса с помощью JavaScript
Есть ли надежный способ получить часовой пояс из клиентского браузера? Я видел следующие ссылки, но мне нужно более надежное решение.
Автоматическое определение часового пояса с помощью JavaScript
Ответы:
Посмотрите на эту страницу репозитория, это полезно
загрузите jstz.min.js и добавьте функцию на свою html-страницу
<script language="javascript">
function getTimezoneName() {
timezone = jstz.determine()
return timezone.name();
}
</script>
и вызовите эту функцию из тега отображения
Intl.DateTimeFormat().resolvedOptions().timeZone(без IE11), как предлагает Уоллес.
Спустя полдесятилетия у нас есть для этого встроенный способ! Для современных браузеров я бы использовал:
const tz = Intl.DateTimeFormat().resolvedOptions().timeZone;
console.log(tz);
Это возвращает строку часового пояса IANA, но не смещение . Узнайте больше в справочнике MDN .
Таблица совместимости - по состоянию на март 2019 года работает для 90% браузеров, используемых во всем мире. Не работает в Internet Explorer .
Intl.DateTimeFormat().resolvedOptions().timeZone->undefined
Intl.DateTimeFormat().resolvedOptions().timeZoneвернет ожидаемое значение, начиная с Firefox 52: kangax.github.io/compat-table/esintl/…
Часто, когда люди ищут «часовые пояса», достаточно просто «смещения UTC». например, их сервер находится в UTC + 5, и они хотят знать, что их клиент работает в UTC-8 .
В простом старом javascript (new Date()).getTimezoneOffset()/60вернет текущее количество часов смещения от UTC.
Стоит отметить возможную "ошибку" в знаке getTimezoneOffset()возвращаемого значения (из документации MDN) :
Смещение часового пояса - это разница в минутах между временем по Гринвичу и местным временем. Обратите внимание: это означает, что смещение положительное, если местный часовой пояс отстает от UTC, и отрицательное, если оно впереди. Например, для часового пояса UTC + 10: 00 (австралийское восточное стандартное время, владивостокское время, стандартное время чаморро) будет возвращено -600.
Однако я рекомендую вам использовать day.js для кода Javascript, связанного с датой и временем. В этом случае вы можете получить смещение UTC в формате ISO 8601, запустив:
> dayjs().format("Z")
"-08:00"
Вероятно, стоит упомянуть, что клиент может легко сфальсифицировать эту информацию.
(Примечание: этот ответ изначально рекомендовал https://momentjs.com/ , но dayjs - более современная альтернатива меньшего размера.)
На данный момент лучшим вариантом, вероятно, будет jstz, как предлагается в ответе mbayloon .
Для полноты картины следует упомянуть, что на подходе есть стандарт: Intl . Вы уже можете увидеть это в Chrome:
> Intl.DateTimeFormat().resolvedOptions().timeZone
"America/Los_Angeles"
(На самом деле это не соответствует стандарту, что является еще одной причиной придерживаться библиотеки)
Intlдолжны возвращаться undefinedдля timeZoneсвойства, если вы не указали вручную часовой пояс при создании DateTimeFormat. Chrome отклоняется от стандарта, вместо этого возвращая системный часовой пояс; это то, что использует ответ Йоханнеса, но также то, почему он сказал, что «на самом деле не соответствует стандарту».
вы можете использовать момент-часовой пояс, чтобы угадать часовой пояс:
> moment.tz.guess()
"America/Asuncion"
Вот jsfiddle
Он обеспечивает сокращение часового пояса текущего пользователя.
Вот пример кода
var tz = jstz.determine();
console.log(tz.name());
console.log(moment.tz.zone(tz.name()).abbr(new Date().getTime()));
May 22 2015 03:45 PM CDT я использовал console.log(moment(now).format('MMM DD YYYY hh:mm A') + ' ' + moment.tz.zone(tz.name()).abbr(now.getTime()));
Я использовал подход, аналогичный подходу, принятому Джошем Фрейзером , который определяет смещение времени браузера от UTC и распознает ли он DST или нет (но несколько упрощено из его кода):
var ClientTZ = {
UTCoffset: 0, // Browser time offset from UTC in minutes
UTCoffsetT: '+0000S', // Browser time offset from UTC in '±hhmmD' form
hasDST: false, // Browser time observes DST
// Determine browser's timezone and DST
getBrowserTZ: function () {
var self = ClientTZ;
// Determine UTC time offset
var now = new Date();
var date1 = new Date(now.getFullYear(), 1-1, 1, 0, 0, 0, 0); // Jan
var diff1 = -date1.getTimezoneOffset();
self.UTCoffset = diff1;
// Determine DST use
var date2 = new Date(now.getFullYear(), 6-1, 1, 0, 0, 0, 0); // Jun
var diff2 = -date2.getTimezoneOffset();
if (diff1 != diff2) {
self.hasDST = true;
if (diff1 - diff2 >= 0)
self.UTCoffset = diff2; // East of GMT
}
// Convert UTC offset to ±hhmmD form
diff2 = (diff1 < 0 ? -diff1 : diff1) / 60;
var hr = Math.floor(diff2);
var min = diff2 - hr;
diff2 = hr * 100 + min * 60;
self.UTCoffsetT = (diff1 < 0 ? '-' : '+') + (hr < 10 ? '0' : '') + diff2.toString() + (self.hasDST ? 'D' : 'S');
return self.UTCoffset;
}
};
// Onload
ClientTZ.getBrowserTZ();
При загрузке выполняется ClientTZ.getBrowserTZ()функция, которая устанавливает:
ClientTZ.UTCoffset к смещению времени браузера от UTC в минутах (например, CST составляет -360 минут, что составляет -6,0 часов от UTC);ClientTZ.UTCoffsetTна смещение в форме '±hhmmD'(например, '-0600D'), где суффикс Dдля DST и Sдля стандартного (не-DST);ClientTZ.hasDST (истинно или ложно).Значение ClientTZ.UTCoffsetуказывается в минутах, а не в часах, поскольку в некоторых часовых поясах почасовые смещения дробные (например, +0415).
Его цель ClientTZ.UTCoffsetT- использовать его в качестве ключа в таблице часовых поясов (здесь не приводится), например, для раскрывающегося <select>списка.
7-1июль вместо июня. Я не уверен, действительно ли это имеет значение, поскольку я сомневаюсь, что существуют региональные схемы летнего времени, которые не включают июнь.
Вот версия, которая хорошо работает в сентябре 2020 года с использованием fetch и https://worldtimeapi.org/api
fetch("https://worldtimeapi.org/api/ip")
.then(response => response.json())
.then(data => console.log(data.timezone,data.datetime,data.dst));
Нет. Единого надежного пути нет и не будет. Вы действительно думали, что можете доверять клиенту?