Есть ли надежный способ получить часовой пояс из клиентского браузера? Я видел следующие ссылки, но мне нужно более надежное решение.
Автоматическое определение часового пояса с помощью JavaScript
javascript
http
browser
timezone
Конфуций
источник
источник
Ответы:
Посмотрите на эту страницу репозитория, это полезно
загрузите 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) :Однако я рекомендую вам использовать 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));
источник
Нет. Единого надежного пути нет и не будет. Вы действительно думали, что можете доверять клиенту?
источник