Відображати дату / час у локальному форматі користувача та зміщення часу


167

Я хочу, щоб сервер завжди розміщував дати в UTC у HTML, а JavaScript на сайті клієнта конвертував його у місцевий часовий пояс користувача.

Бонус, якщо я можу вивести у форматі дати місцевого користувача користувача.

Відповіді:


165

Здається, найбезпечніший спосіб почати з дати UTC - це створити новий Dateоб’єкт і використовуватиsetUTC… методів для встановлення потрібної дати / часу.

Тоді різні toLocale…Stringметоди забезпечать локалізований вихід.

Приклад:

// This would come from the server.
// Also, this whole block could probably be made into an mktime function.
// All very bare here for quick grasping.
d = new Date();
d.setUTCFullYear(2004);
d.setUTCMonth(1);
d.setUTCDate(29);
d.setUTCHours(2);
d.setUTCMinutes(45);
d.setUTCSeconds(26);

console.log(d);                        // -> Sat Feb 28 2004 23:45:26 GMT-0300 (BRT)
console.log(d.toLocaleString());       // -> Sat Feb 28 23:45:26 2004
console.log(d.toLocaleDateString());   // -> 02/28/2004
console.log(d.toLocaleTimeString());   // -> 23:45:26

Деякі посилання:


1
У Firefox toLocateDateString()повертає щось таке, що виглядає як "неділя, 12 січня 2014 року" ..
BlueRaja - Danny Pflughoeft

1
Хм, так, це досить серйозна проблема. Використання цих методів не допоможе, якщо ви хочете, щоб дата виглядала однаково у веб-переглядачах. Будь-які альтернативи відомі?
Джош Мак

6
Однорядкова версія вищезазначеної ініціалізації:var d = new Date(Date.UTC(2004,1,29,2,45,26));
m1kael

4
Можливо, варто врахувати, що Chrome (станом на v35) не враховує локальну функцію користувача у toLocaleString()функціях.
benno

8
Вибачте, але цей метод не працює внизу (я в Австралії), коли я запускаю вищезгаданий код, дата відображається у форматі США. Крім того, MDN каже, що "використовуваний локал та форма рядка, що повертається, повністю залежать від реалізації".
tgrrr

65

Для нових проектів просто використовуйте moment.js

Це питання досить старе, тому moment.js тоді не існувало, але для нових проектів воно дуже спрощує такі завдання.

Найкраще проаналізувати рядок дати з UTC таким чином (створити на сервері сумісну рядок ISO-8601, щоб отримати стійкі результати у всіх браузерах):

var m = moment("2013-02-08T09:30:26Z");

Тепер просто використовуйте mу своїй програмі для операцій з відображенням параметр moment.js за замовчуванням у локальному часовому поясі. Існує багато способів відформатувати значення дати та часу або витягнути їх частини.

Ви навіть можете відформатувати об'єкт моменту в мовній користувачі так:

m.format('LLL') // Returns "February 8 2013 8:30 AM" on en-us

Щоб перетворити об’єкт moment.js в інший часовий пояс (тобто не локальний, ані UTC), вам знадобиться розширення часового поясу moment.js . На цій сторінці також є кілька прикладів, це досить просто у використанні.


Як ви поєднуєте все це? m.utcOffset (offset) .format ('LLL'), здається, не працює.
барт

Чи повинні Луксон або Day.js бути запропонованою бібліотекою зараз?
Гомер

1
Пропоную додатиFor old projects, just use jQuery
Xenos

Не працює на хромі - все ще показує ранку / вечір, навіть якщо в локальних налаштуваннях комп’ютера встановлено 24 години
нас

20

Ви можете використовувати new Date().getTimezoneOffset()/60для часового поясу. Також єtoLocaleString() спосіб відображення дати за допомогою локальної функції користувача.

Ось весь список: Робота з датами


toLocaleString є вкрай ненадійним для представлення дат у форматі, який може очікувати користувач. Навіть там, де підтримується ISO 402, він все ще дуже ненадійний і базує формат на мові, а не на локалі.
RobG

@RobG що таке рішення замість toLocaleString?
user924

@ user924 - ви можете використовувати бібліотеку, з чого можна вибрати. Проблема з toLocaleString полягає в тому, що різні реалізації дають різні результати з різним рівнем підтримки для різних мов та регіонів. Наприклад, для моєї системи за замовчуванням мова не в американській мові, але формат toLocaleString за умовчанням для деяких браузерів - це формат США, а інші поважають мою системну мову. Те саме саме з назвами часових поясів, тільки гірше, оскільки вони зовсім не стандартизовані. :-(
RobG

7

Після створення об’єкта дати, ось фрагмент конверсії:

Ця функція приймає об'єкт дати та формат, відформатований UTC.
Вам знадобиться Date.strftimeпрототип.

function UTCToLocalTimeString(d, format) {
    if (timeOffsetInHours == null) {
        timeOffsetInHours = (new Date().getTimezoneOffset()/60) * (-1);
    }
    d.setHours(d.getHours() + timeOffsetInHours);

    return d.strftime(format);
}

6
звідки у вас стрімкінг?
Ануй Пандей

Чи впливає встановлення годин на частини День / Дата / Рік об’єкта Дата? Не здається.
ChristoKiwi

1
@ ChristoKiwi - очікується, що значення, передане setHours , буде цілим числом, getTimezoneOffset()/60може повернути дріб (наприклад, зміщення Індії +05: 30 поверне 5,5). Десяткові знаки відсікаються. В іншому випадку, встановлення годин оновить інші значення (встановіть години на 48 і подивіться, що відбувається).
RobG

7

У JS не існує простих та міжплатформних способів форматування локального часу дати, крім перетворення кожного ресурсу, як було зазначено вище.

Ось швидкий злом, який я використовую, щоб отримати місцевий YYYY-MM-DD. Зауважте, що це злом, оскільки кінцева дата більше не матиме правильного часового поясу (тому вам доведеться ігнорувати часовий пояс). Якщо мені потрібно ще щось, я використовую moment.js.

var d = new Date();    
d = new Date(d.getTime() - d.getTimezoneOffset() * 60000)
var yyyymmdd = t.toISOString().slice(0,0); 
// 2017-05-09T08:24:26.581Z (but this is not UTC)

D.getTimezoneOffset () повертає зміщення часового поясу за хвилини, а d.getTime () - у мс, отже, x 60 000.


1
@VG Я додав додаткову інформацію про те, звідки береться 60k. Сподіваюся, що це допоможе.
Джеремі Чоне

5

Ось що я використовував у минулих проектах:

var myDate = new Date();
var tzo = (myDate.getTimezoneOffset()/60)*(-1);
//get server date value here, the parseInvariant is from MS Ajax, you would need to do something similar on your own
myDate = new Date.parseInvariant('<%=DataCurrentDate%>', 'yyyyMMdd hh:mm:ss');
myDate.setHours(myDate.getHours() + tzo);
//here you would have to get a handle to your span / div to set.  again, I'm using MS Ajax's $get
var dateSpn = $get('dataDate');
dateSpn.innerHTML = myDate.localeFormat('F');

4
Це стосується специфічних для ASP.NET матеріалів.
ZiggyTheHamster

Зсуви часового поясу не обов’язково навіть кратні годині, тому getTimezoneOffset()/60часто повертають десяткове значення. Особливо це стосується дат до 1900 року, коли в багатьох місцях відбулося зміщення хвилин і секунд. Крім того, зараз потрібні дати JavaScript для підтримки історичних зрушень. Наприклад, у 1890 р. Компенсація в Москві становила +2: 30: 17. Див. Веб-переглядачі, часові пояси, помилка Chrome 67 .
RobG

3

The .getTimezoneOffset()Метод повідомляє зміщення часового поясу в хвилинах, підрахунок «захід» з тимчасової зони GMT / UTC, в результаті чого значення зсуву , що негативно до того , що один зазвичай звик. (Наприклад, повідомляється, що нью-йоркський час становитиме +240 хвилин або +4 години)

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

var timeOffsetInHours = -(new Date()).getTimezoneOffset()/60

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


3

З датою PHP-коду я використав щось подібне ..

function getLocalDate(php_date) {
  var dt = new Date(php_date);
  var minutes = dt.getTimezoneOffset();
  dt = new Date(dt.getTime() + minutes*60000);
  return dt;
}

Ми можемо назвати це так

var localdateObj = getLocalDate('2015-09-25T02:57:46');

Питання стосувалося JavaScript, а не PHP.
pipedreambomb

5
Відповідь лише у javascript, в питанні зазначається, що дата сервера знаходиться в UTC. тому сервер може бути будь-якою мовою. тому я відповів лише на PHP
hriziya

3

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

Рядок datetime походить від db python / django у форматі: 2016-12-05T15: 12: 24.215Z

Надійне виявлення мови браузера в JavaScript, здається, не працює у всіх браузерах (див. JavaScript для виявлення переваг мови браузера ), тому я отримую мову браузера з сервера.

Python / Django: надіслати мову браузера запиту як параметр контексту:

language = request.META.get('HTTP_ACCEPT_LANGUAGE')
return render(request, 'cssexy/index.html', { "language": language })

HTML: запишіть його в прихований вхід:

<input type="hidden" id="browserlanguage" value={{ language }}/>

JavaScript: отримайте значення прихованого вводу, наприклад en-GB, en-US; q = 0.8, en; q = 0.6 /, а потім візьміть першу мову у списку лише за допомогою заміни та регулярного виразу

const browserlanguage = document.getElementById("browserlanguage").value;
var defaultlang = browserlanguage.replace(/(\w{2}\-\w{2}),.*/, "$1");

JavaScript: перетворити в дату і відформатувати його:

var options = { hour: "2-digit", minute: "2-digit" };
var dt = (new Date(str)).toLocaleDateString(defaultlang, options);

Дивіться: https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Date/toLocaleDateString

Результат (мова браузера en-gb): 12.05.2016, 14:58


3

// new Date(year, monthIndex [, day [, hours [, minutes [, seconds [, milliseconds]]]]])
var serverDate = new Date(2018, 5, 30, 19, 13, 15); // just any date that comes from server
var serverDateStr = serverDate.toLocaleString("en-US", {
  year: 'numeric',
  month: 'numeric',
  day: 'numeric',
  hour: 'numeric',
  minute: 'numeric',
  second: 'numeric'
})
var userDate = new Date(serverDateStr + " UTC");
var locale = window.navigator.userLanguage || window.navigator.language;

var clientDateStr = userDate.toLocaleString(locale, {
  year: 'numeric',
  month: 'numeric',
  day: 'numeric'
});

var clientDateTimeStr = userDate.toLocaleString(locale, {
  year: 'numeric',
  month: 'numeric',
  day: 'numeric',
  hour: 'numeric',
  minute: 'numeric',
  second: 'numeric'
});

console.log("Server UTC date: " + serverDateStr);
console.log("User's local date: " + clientDateStr);
console.log("User's local date&time: " + clientDateTimeStr);


Довідково: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… (мені потрібна була optionsчастина для моєї справи)
Xenos,

2

Найкраще рішення, з яким я зіткнувся, - створити теги [time display = "llll" datetime = "UTC TIME" /], а також використовувати javascript (jquery) для розбору та відображення його відносно часу користувача.

http://momentjs.com/ Moment.js

покаже час чудово.


2

Ви можете використовувати наступне, що повідомляє про зміщення часового поясу від GMT за хвилини:

new Date().getTimezoneOffset();

Примітка: - ця функція повертає від’ємне число.


1

getTimeZoneOffset () і toLocaleString хороші для основної роботи з датами, але якщо вам потрібна реальна підтримка часового поясу, подивіться на TimeDone.js mde .

У відповіді на це питання розглянуто ще кілька варіантів


1

Для перетворення дати в локальну дату використовуйте метод toLocaleDateString ().

var date = (new Date(str)).toLocaleDateString(defaultlang, options);

Для перетворення часу на місцевий час використовуйте метод toLocaleTimeString ().

var time = (new Date(str)).toLocaleTimeString(defaultlang, options);

-12

Не знаю, як зробити локаль, але javascript - це технологія на стороні клієнта.

usersLocalTime = new Date();

матиме в ньому час та дату клієнта (як повідомляється у його браузері та за розширенням комп'ютера, на якому вони сидять). Доцільно включити час відповіді сервера у відповідь і зробити просту математику, щоб відгадати-компенсувати зміщення.

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