Отримання часового поясу клієнта в JavaScript


613

Як я можу зібрати інформацію про часовий пояс відвідувача? Мені потрібні Часовий пояс, а також години зміщення GMT.


3
Я зараз розумію ту саму проблему. Ось цікавий підхід.
Тамаш Пап

31
Заголовок запитує часовий пояс, тоді як текст запитує зміщення GMT. Це 2 різні речі. Часовий пояс включає інформацію про DST, зміщення utc не робить. У часовій зоні є ім’я та історія, зміщення не відбувається. Рекомендуйте відредагувати заголовок у розділі "Отримання компенсації gmt клієнта у JS".
citykid

Мені потрібен часовий пояс. Зміщення GMT також було б корисно.
DaveWalley

9
Відповіді тут зосереджуються переважно на компенсуванні . Для часового поясу дивіться цю відповідь . Дивіться "Часова зона! = Зсув" у вікі тегів часового поясу .
Метт Джонсон-Пінт

7
Ви отримаєте точний часовий пояс, скориставшись цим Intl.DateTimeFormat (). Вирішеними варіантами (). TimeZone
Mangesh Mandavgane

Відповіді:


594

var offset = new Date().getTimezoneOffset();
console.log(offset);

Зсув часового поясу - це різниця в хвилинах між UTC та місцевим часом. Зауважте, що це означає, що зсув є позитивним, якщо локальний часовий пояс знаходиться за UTC і негативним, якщо він попереду. Наприклад, якщо ваш часовий пояс становить UTC + 10 (австралійський східний стандартний час), повернеться -600. Перехід на літній час заважає цьому значенню бути постійним навіть для певного місця

Зауважте, що не всі часові пояси зміщені цілими годинами: наприклад, у Ньюфаундленді UTC мінус 3 год 30 м (вихід літнього часу не виходить із рівняння).


42
@abernier Чи діє заява про getTimezoneOffsetнеточність? Стаття, на яку ви посилаєтесь, датована червнем 2007 року і не містить деталей про те, як функція є неточною. А насправді бібліотека, jsTimezoneDetectяку ви вказали, використовує getTimezoneOffsetсама.
Майк

5
@abernier Це стандарт з ES 1, тому я впевнений, що будь-яка проблема з реалізацією може бути вже виправлена, я маю на увазі, що це стаття 7 років.
LasagnaAndroid

49
var hrs = -(new Date().getTimezoneOffset() / 60) для компенсації в звичайних годинах
Едвін Даніельс

6
Здається, це не враховує літній час
Шахдат

21
timezone! =utc offset
bendytree

480

Використання зміщення для обчислення часової зони - це неправильний підхід, і ви завжди будете стикатися з проблемами. Часові пояси та правила літнього часу можуть змінюватися протягом декількох випадків протягом року, і важко не відставати від змін.

Щоб отримати часовий пояс IANA системи в JavaScript, ви повинні використовувати

console.log(Intl.DateTimeFormat().resolvedOptions().timeZone)

Станом на вересень 2019 року це працює у 95% браузерів, які використовуються у всьому світі .

Стара інформація про сумісність

ecma-402 / 1.0 говорить, що це timeZoneможе бути невизначено, якщо його не надано конструктору. Однак майбутній проект (3.0) вирішив цю проблему, змінивши часовий пояс системи за замовчуванням.

У цій версії API інтернаціоналізації ECMAScript timeZoneвластивість залишатиметься невизначеною, якщо timeZoneв об'єкті параметрів, наданих Intl.DateTimeFormat конструктору, не було надано жодного властивості . Однак програми не повинні покладатися на це, оскільки майбутні версії можуть натомість повертати значення String, що ідентифікує поточний часовий пояс хост-середовища.

в ecma-402 / 3.0, який все ще знаходиться в чернеті, на який він змінився

У цій версії API інтернаціоналізації ECMAScript 2015 timeZoneвластивість буде іменем часового поясу за замовчуванням, якщо timeZoneв об'єкті параметрів, наданих Intl.DateTimeFormatконструктору, не було вказано властивості . Попередня версія залишила timeZoneвластивість невизначеною у цьому випадку.


17
Це єдина відповідь на отримання часового поясу, який може знадобитися деяким користувачам на відміну від зсуву. Отже, як оновлення у 2016-09 роках, Intl працює на більшості сучасних браузерів, але не на Safari. Для цього веб-переглядача тут досить точний запас JavaScript - pellepim.bitbucket.org/jstz
user2085368

6
Перевірено, що зараз це працює у Safari. (Використовується версія 10.0)
BadPirate

2
Було б добре, якби це працювало у всіх сучасних браузерах. Однак IE11 та остання Firefox повертаються невизначеними для властивості timeZone.
Хапрог

7
Зараз я перевірив Chrome 58, Edge 40 та Firefox 53 - це працює, і всі вони. Це не працює з IE 11, я не тестував Opera.
Сума

7
Знадобилося деякий час, щоб знайти список часових поясів, повернутих цим API. Ось це: en.wikipedia.org/wiki/List_of_tz_database_time_zones
Xavier Poinas

123

Я усвідомлюю, що ця відповідь трохи поза темою, але я думаю, що багато хто з нас шукає відповіді, хотіли також відформатувати часовий пояс для відображення і, можливо, отримати абревіатуру зони. Так ось це йде ...

Якщо ви хочете, щоб часовий пояс клієнта був добре відформатований, ви можете покластися на метод JavaScript Date.toString JavaScript і зробити:

var split = new Date().toString().split(" ");
var timeZoneFormatted = split[split.length - 2] + " " + split[split.length - 1];

Це дасть вам "GMT-0400 (EST)", наприклад, включаючи хвилини часового поясу, коли це застосовується.

Крім того, за допомогою регексу ви можете витягти будь-яку бажану частину:

Для "GMT-0400 (EDT)":

new Date().toString().match(/([A-Z]+[\+-][0-9]+.*)/)[1]

Для "GMT-0400":

new Date().toString().match(/([A-Z]+[\+-][0-9]+)/)[1]

Щойно для "EDT":

new Date().toString().match(/\(([A-Za-z\s].*)\)/)[1]

Всього за "-0400":

new Date().toString().match(/([-\+][0-9]+)\s/)[1]

Посилання Date.toString: https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Date/toString


4
Зламано з Chrome, оскільки він додає назву часового поясу. Не використовуйте натомість split.length, а константу split[4] + " " + split[5]?!
Крістоф Руссі

4
Це також не працює (здивування, здивування) IE. Я щойно зробив консольний дамп об’єкта об'єкта Date. Це те саме в Chrome, Firefox та Safari, але відрізняється IE. Отже, ви також не можете розраховувати на постійні індекси. Пн 02 грудня 2013 10:22:50 GMT-0500 (EST): Chrome, FF, Safari; Пн 2 грудня 10:22:50 EST 2013:
IE10

1
Дякую, дякую! Я стрибав через обручі, намагаючись відобразити часовий пояс браузера ..... ew Date (). ToString (). Match (/ ([AZ] + [\ + -] [0-9] +. *) /) [ 1] було саме те, що мені потрібно!
KiwiSunGoddess

1
Це не працює. Для мене splitміститься: ["Mon", "Mar", "13", "2017", "14:05:22", "GMT-0400", "(Eastern", "Daylight", "Time)"]тому результатDaylight Time)
DLeh

7
Це насправді не дуже гарна ідея, що фактичне представлення часу JS після того, як ви це зробите new Date().toString(), повністю залежить від ваших налаштувань мови. Очікувати результатів інших клієнтів схожих на ваші - дуже погана ідея.
Восьминіг

71

Вже відповіли, як компенсувати за хвилини як ціле число, але у випадку, якщо хтось хоче, щоб локальний GMT змістився як рядок, наприклад "+1130":

function pad(number, length){
    var str = "" + number
    while (str.length < length) {
        str = '0'+str
    }
    return str
}

var offset = new Date().getTimezoneOffset()
offset = ((offset<0? '+':'-')+ // Note the reversed sign!
          pad(parseInt(Math.abs(offset/60)), 2)+
          pad(Math.abs(offset%60), 2))

1
Вам потрібно замінити першу підкладку, pad(parseInt(Math.abs(offset/60)), 2)щоб виправити це ... інакше ви можете в кінцевому підсумку отримати +5.530, як у моєму випадку ... я не впевнений, що математичний підлогу тощо буде кращою справою тут чи ні .... але це atleast дає мені +0530 як очікувалося
Abhinav Singh

Саме те, що я шукав. Дякую !
codenooker

це дасть правильний результат: this.pad (Math.floor ((Math.abs (offset / 60))), 2)
Vivek

Замість того, щоб використовувати функцію колодки, мені це легше зробити: offset = (зміщення <0? "+": "-") + ("0000" + parseInt ((Math.abs (offset / 60)))) .slice (-4)
flurbius

67

Ви можете використовувати:

момент-часовий пояс

<script src="moment.js"></script>
<script src="moment-timezone-with-data.js"></script>

// retrieve timezone by name (i.e. "America/Chicago")
moment.tz.guess();

Виявити часовий пояс у веб-переглядачі досить складно, щоб правильно підібрати, оскільки браузер має мало інформації.

Момент Timezone використовує Date.getTimezoneOffset()і Date.toString()в кілька моментів навколо поточного року, щоб зібрати якомога більше інформації про середовище браузера. Потім вона порівнює цю інформацію з усіма завантаженими даними часового поясу і повертає найближчу відповідність. У разі зв’язків повертається часовий пояс з містом з найбільшим населенням.

console.log(moment.tz.guess()); // America/Chicago

12
Це має бути прийнятою відповіддю. Це єдиний, який дає фактичну назву часового поясу, а не зміщення. Пам'ятайте, що зміщення часового поясу можна отримати від імені, навпаки не вірно. Через DST та інші тонкощі, кілька часових поясів можуть мати однаковий зміщення лише в певні дні року.
Romain G

1
Зараз для цього існує власне рішення - Intl API . У той час, коли moment.js був чудовою бібліотекою ще в той час, на сьогоднішній день є набагато менші альтернативи ( dayjs , date-fns ). Момент величезний ; будь ласка, не рекомендую це для клієнтських програм.
Дан Даскалеску

43

Я написав функцію у своєму проекті, яка повертає часовий пояс у hh:mmформаті. Я сподіваюся, що це може допомогти комусь:

function getTimeZone() {
    var offset = new Date().getTimezoneOffset(), o = Math.abs(offset);
    return (offset < 0 ? "+" : "-") + ("00" + Math.floor(o / 60)).slice(-2) + ":" + ("00" + (o % 60)).slice(-2);
}

// Outputs: +5:00

Робоча скрипка


1
Дякую! Це те, що мені було потрібно!
Джеремі Моріц

15

Однолінійний параметр, який надає і зміщення, і часовий пояс, - це просто зателефонувати toTimeString () на новий об'єкт Date. Від MDN:

toTimeString()Метод повертає тимчасову частину об'єкта Date в читабельною формі на американському англійською.

Проблема полягає в тому, що часовий пояс не в стандартному форматі IANA; це дещо зручніший користувач, ніж формат IANA "континент / місто" . Спробуй:

console.log(new Date().toTimeString().slice(9));
console.log(Intl.DateTimeFormat().resolvedOptions().timeZone);
console.log(new Date().getTimezoneOffset() / -60);

Зараз у Каліфорнії toTimeString()повертається, Pacific Daylight Timeпоки повертається API Intl America/Los_Angeles. У Колумбії, ви отримаєте Colombia Standard Time, проти America/Bogota.

Зауважте, що багато інших відповідей на це питання намагаються отримати ту саму інформацію, зателефонувавши на Date.toString (). Цей підхід не такий надійний, як пояснює MDN :

Екземпляри дати посилаються на певний момент часу. Зателефонувавши до toString (), повернеться дата, відформатована у читаній людиною формі в американській англійській мові. [...] Іноді бажано отримати рядок часової частини; таке може бути здійснено toTimeString()методом.

toTimeString()Метод особливо корисний , так як сумісні двигуни , які реалізують ECMA-262 можуть відрізнятися в рядку , отриманої з toString()для Dateоб'єктів, так як формат залежить від реалізації; прості підходи до нарізки рядків можуть не давати стійких результатів у кількох двигунах.


13

спробуйте getTimezoneOffset()на Dateоб'єкті:

var curdate = new Date()
var offset = curdate.getTimezoneOffset()

Цей метод повертає зміщення часового поясу в хвилинах, що є різницею між GMT та місцевим часом у хвилинах.



7

З моментом.js :

moment().format('zz');

6
zі zzзастаріли станом на 1.6.0, див. momentjs.com/docs/#/displaying/format
MrUpsidown,

3
@MrUpsidown це зараз ZіZZ
brauliobo

4
@brauliobo Ці параметри не повертають одне і те ж. z і zz повернули часовий пояс, наприклад, CST, але Z і ZZ повертають зміщення, наприклад -0600.
Лука Спіллер

Останні покази документів .zoneAbbr()замінили zі zz. Дивіться документацію тут
tabish89

1
У той час, коли moment.js був чудовою бібліотекою ще в той час, на сьогоднішній день є набагато менші альтернативи ( dayjs , date-fns ). Момент величезний ; будь ласка, не рекомендую це для клієнтських програм.
Дан Даскалеску

6

З , Ви можете знайти поточний часовий пояс як

console.log(moment().utcOffset()); // (-240, -120, -60, 0, 60, 120, 240, etc.)
<script src="https://cdn.jsdelivr.net/momentjs/2.13.0/moment.min.js"></script>


З , Ви можете знайти поточний часовий пояс як

console.log(dayjs().utcOffset()); // (-240, -120, -60, 0, 60, 120, 240, etc.)
<script src="https://unpkg.com/dayjs@1.8.10/dayjs.min.js"></script>

Обидва API повертають utc offset за лічені хвилини.


У той час, коли moment.js був чудовою бібліотекою ще в той час, на сьогоднішній день є набагато менші альтернативи ( dayjs , date-fns ). Момент величезний ; будь ласка, не рекомендую це для клієнтських програм.
Дан Даскалеску

1
"За допомогою dayjs ви можете знайти поточний часовий пояс, оскільки" не зовсім точний - ви знайдете лише зміщення, а не часовий пояс . Також у Dayjs немає підтримки часового поясу . Його метод .utcOffset () є просто оболонкою над рідною getTimezoneOffset().
Дан Даскалеску

4

Часовий пояс у годинах-

var offset = new Date().getTimezoneOffset();
if(offset<0)
    console.log( "Your timezone is- GMT+" + (offset/-60));
else
    console.log( "Your timezone is- GMT-" + offset/60);

Якщо ви хочете бути точними, як ви згадували в коментарі, тоді вам слід спробувати так -

var offset = new Date().getTimezoneOffset();

if(offset<0)
{
    var extraZero = "";
    if(-offset%60<10)
      extraZero="0";

    console.log( "Your timezone is- GMT+" + Math.ceil(offset/-60)+":"+extraZero+(-offset%60));
}
else
{
    var extraZero = "";
    if(offset%60<10)
      extraZero="0";

    console.log( "Your timezone is- GMT-" + Math.floor(offset/60)+":"+extraZero+(offset%60));
}


Не працює для часових поясів, коли це не повна година, як Венесуела, куди повертається GMT-4.5
Mirko

Так це правильно. 0,5 означає 0,5 * 30 хв. Я думаю, ти це зрозумів, чому він дає 0,5?
Абрар Джахін

так, тому GMT-4.5 не є дійсним часовим поясом, йому потрібно трохи додаткового розбору, щоб стати GMT-4: 30
Mirko

@Mirko зараз друга частина відповіді саме для вас
Абрар Джахін

Якщо ви хочете бути більш точними, використовуйте UTC замість GMT, [Hilton and McCarthy 2013, p. 231–2. ], дивіться також у wikipedia GMT - ( en.wikipedia.org/wiki/Greenwich_Mean_Time )
Том

3

Якщо все, що вам потрібно, це "MST" або абревіатура часового поясу "EST":

function getTimeZone(){
    var now = new Date().toString();
    var timeZone = now.replace(/.*[(](.*)[)].*/,'$1');//extracts the content between parenthesis
    return timeZone;
}

Використання Date.toString()не є надійним, і MDN пояснює, чому. Я вставив відповідний розділ з їх документації в моїй обороні .
Дан Даскалеску

3

Дивіться, що цей оператор в результаті був протилежним часовій зоні. Тому застосуйте математичну функцію, а потім підтвердіть число менше або більше.

введіть тут опис зображення

Див. Документ MDN

var a = new Date().getTimezoneOffset();

var res = -Math.round(a/60)+':'+-(a%60);
res = res < 0 ?res : '+'+res;

console.log(res)


1
у випадку негативного значення, якась проблема
Arun Prasad ES

1
Чому round? Це повинно бути floor, чи не так?
Qwertiy

3
function getLocalTimeZone() {
    var dd = new Date();
    var ddStr = dd.toString();
    var ddArr = ddStr.split(' ');
    var tmznSTr = ddArr[5];
    tmznSTr = tmznSTr.substring(3, tmznSTr.length);
    return tmznSTr;
}

Приклад: Чт 21 червня 2018 18:12:50 GMT + 0530 (Індійський стандартний час)

O / P: +0530


Використання Date.toString()не є надійним, і MDN пояснює, чому. Я вставив відповідний розділ з їх документації в моїй обороні .
Дан Даскалеску


2

Це значення є з машини користувача, і його можна змінити будь-коли, тому я думаю, що це не має значення, я просто хочу отримати приблизне значення, а потім перетворити його на GMT на своєму сервері.

Наприклад, я з Тайваню, і він повертає "+8" для мене.

Робочий приклад

JS

function timezone() {
    var offset = new Date().getTimezoneOffset();
    var minutes = Math.abs(offset);
    var hours = Math.floor(minutes / 60);
    var prefix = offset < 0 ? "+" : "-";
    return prefix+hours;
}


$('#result').html(timezone());

HTML

<div id="result"></div>

Результат

+8

2

У new Date() ви можете отримати зміщення, щоб отримати ім'я часового поясу, яке ви можете виконати:

new Date().toString().replace(/(.*\((.*)\).*)/, '$2');

ви отримуєте значення між ()в кінці дати, тобто назвою часового поясу.


Використання Date.toString()не є надійним, і MDN пояснює, чому. Я вставив відповідний розділ з їх документації в моїй обороні . Також ця відповідь дана вже щонайменше 3 рази.
Дан Даскалеску

2

Це було б моє рішення:


    // For time zone:
    const timeZone = /\((.*)\)/.exec(new Date().toString())[1];
    
    // Offset hours:
    const offsetHours = new Date().getTimezoneOffset() / 60;
    
    console.log(`${timeZone}, ${offsetHours}hrs`);

1

Як альтернативу new Date().getTimezoneOffset()і moment().format('zz'), ви також можете використовувати:

var offset = moment.parseZone(Date.now()).utcOffset() / 60
console.log(offset);
<script src="https://cdn.jsdelivr.net/momentjs/2.13.0/moment.min.js"></script>

jstimezone також є досить гнучким і незмінним ( https://bitbucket.org/pellepim/jstimezonedetect/isissue?status=new&status=open )


У той час, коли moment.js був чудовою бібліотекою ще в той час, на сьогоднішній день є набагато менші альтернативи ( dayjs , date-fns ). Момент величезний ; будь ласка, не рекомендую це для клієнтських програм.
Дан Даскалеску

1

Використовуйте це, щоб перетворити OffSet в postive:

var offset = new Date().getTimezoneOffset();
console.log(offset);
this.timeOffSet = offset + (-2*offset);
console.log(this.timeOffSet);

-2

Я шукав лише 3-х рядкову рядок (як-от "PDT") і спробував відповісти Маркеса, але довелося трохи налаштувати його для підтримки крос-браузера. На щастя, рядок - це останній потенційний збіг :)

Ось що я зробив у програмі CoffeeScript:

browserTimezone = ->
  userDate = new Date()
  zoneMatches = userDate.toString().match(/([A-Z][A-Z][A-Z])/g)
  userZone = zoneMatches[zoneMatches.length - 1]

Працює в IE8, IE9, Safari 9, Firefox 44 та Chrome 48


2
Однак є часові пояси з чотирма літерами - будьте обережні: наприклад, CEST (Центральноєвропейський літній час)
jbrosi

Використання Date.toString()не є надійним, і MDN пояснює, чому. Я вставив відповідний розділ з їх документації в моїй обороні .
Дан Даскалеску

-3

Вам потрібно лише включити moment.js та jstz.js

<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.17.1/moment.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jstimezonedetect/1.0.6/jstz.min.js"></script>

і після цього

<script>
$(function(){
 var currentTimezone = jstz.determine();
 var timezone = currentTimezone.name();
 alert(timezone);
});

</script>

-3

Це дуже гарна робота для мене:

// Translation to offset in Unix Timestamp
let timeZoneOffset = ((new Date().getTimezoneOffset())/60)*3600;

1
Будь-яке пояснення?

-4

ви можете просто спробувати це. це поверне вам поточний час роботи машини

var _d = new Date(), t = 0, d = new Date(t*1000 + _d.getTime())


Ось як це слід зробити. Я думаю: new Date(new Date().getTime()); він відобразив би: "Пт 28 грудня 2018 10:15:23 GMT + 0100 (Центральноєвропейський стандартний час) {}"
darmis

-4

Це зробить роботу.


var time = new Date(),
timestamp = Date(1000 + time.getTime());
console.log(timestamp);

Thu May 25 2017 21:35:14 GMT+0300 (IDT)

невизначений

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.