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


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.