Чи є надійний спосіб отримати часовий пояс із браузера клієнта? Я бачив наступні посилання, але хочу більш надійного рішення.
Автоматичне виявлення часового поясу за допомогою JavaScript
Чи є надійний спосіб отримати часовий пояс із браузера клієнта? Я бачив наступні посилання, але хочу більш надійного рішення.
Автоматичне виявлення часового поясу за допомогою JavaScript
Відповіді:
Подивіться на це сховище pageloom корисно
завантажте 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 і негативним, якщо він попереду. Наприклад, для часового поясу 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
для стандартного (non-DST);ClientTZ.hasDST
(до істинного чи хибного).ClientTZ.UTCoffset
Надається протягом декількох хвилин , а не годин, тому що деякі часові пояси мають дробові часові зміщення (наприклад, +0415).
Завдання ClientTZ.UTCoffsetT
полягає в тому, щоб використовувати його в якості ключа в таблиці часових поясів (тут не вказано), наприклад, у спадному <select>
списку.
7-1
липень замість червня. Я не впевнений, чи насправді це має значення, оскільки я сумніваюся, що існують регіональні схеми DST, які не включають червень.
Ні. Єдиного надійного способу немає і його ніколи не буде. Ви справді думали, що можете довіряти клієнту?