Отображение даты/времени в формате локали пользователя и смещении времени.
-
01-07-2019 - |
Вопрос
Я хочу, чтобы сервер всегда обслуживал даты в формате UTC в HTML, а JavaScript на клиентском сайте преобразовывал их в местный часовой пояс пользователя.
Бонус, если я смогу вывести дату в формате даты, используемом пользователем.
Решение
Кажется, самый надежный способ начать с даты 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
Некоторые ссылки:
Другие советы
Для новых проектов просто используйте момент.js
Этот вопрос довольно старый, поэтому момент.js в то время не существовало, но для новых проектов это значительно упрощает подобные задачи.
Лучше всего анализировать ваша строка даты из UTC следующим образом (создайте ИСО-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.На этой странице также есть несколько примеров, ее довольно просто использовать.
Вы можете использовать new Date().getTimezoneOffset()/60
для часового пояса.Существует также toLocaleString()
метод отображения даты с использованием локали пользователя.
Вот весь список: Работа с датами
Как только вы создадите объект даты, вот фрагмент для преобразования:
Функция принимает объект Date в формате 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);
}
В JS нет простых и кроссплатформенных способов форматирования локальной даты и времени, кроме преобразования каждого свойства, как упомянуто выше.
Вот быстрый способ, который я использую, чтобы получить местный формат ГГГГ-ММ-ДД.Обратите внимание, что это хак, поскольку конечная дата больше не будет иметь правильный часовой пояс (поэтому вам придется игнорировать часовой пояс).Если мне нужно что-то еще, я использую 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.
Вот что я использовал в прошлых проектах:
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');
А .getTimezoneOffset()
Метод сообщает смещение часового пояса в минутах, считая «на запад» от часового пояса GMT/UTC, в результате чего значение смещения становится отрицательным по сравнению с тем, к чему обычно привыкли.(Например, время в Нью-Йорке будет +240 минут или +4 часа)
Чтобы получить нормальное смещение часового пояса в часах, вам нужно использовать:
var timeOffsetInHours = -(new Date()).getTimezoneOffset()/60
Важная деталь:
Обратите внимание, что в результат учтено летнее время, так что этот метод на самом деле дает вам время смещение - не фактическое географическое часовой пояс компенсировать.
С датой из 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');
Пока я смешиваю ответы и добавляю к ним, потому что мне пришлось прочитать их все и какое-то время дополнительно исследовать, чтобы отобразить строку даты и времени из базы данных в формате местного часового пояса пользователя.
Строка даты и времени поступает из базы данных Python/Django в формате:12/05/2016 15:12:24
Надежное определение языка браузера в JavaScript, похоже, работает не во всех браузерах (см. JavaScript для определения языковых предпочтений браузера), поэтому я получаю язык браузера с сервера.
Питон/Джанго:отправить запрос языка браузера в качестве параметра контекста:
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);
Результат (язык браузера — en-gb):12.05.2016, 14:58
Лучшее решение, с которым я столкнулся, — это создать теги [time display="llll" datetime="UTC TIME" /] и использовать javascript (jquery) для его анализа и отображения относительно времени пользователя.
http://momentjs.com/ Момент.js
будет хорошо отображать время.
Вы можете использовать следующее, которое сообщает о смещении часового пояса от GMT в минутах:
new Date().getTimezoneOffset();
Примечание :- эта функция возвращает отрицательное число.
getTimeZoneOffset() и toLocaleString хороши для базовой работы с датами, но если вам нужна поддержка реального часового пояса, посмотрите TimeZone.js от mde.
В ответе на вопрос обсуждаются еще несколько вариантов. этот вопрос
// 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);
Чтобы преобразовать дату в локальную дату, используйте метод toLocaleDateString().
var date = (new Date(str)).toLocaleDateString(defaultlang, options);
Чтобы преобразовать время в местное время, используйте метод toLocaleTimeString().
var time = (new Date(str)).toLocaleTimeString(defaultlang, options);
Не знаю, как это сделать, но javascript — это технология на стороне клиента.
usersLocalTime = new Date();
будет содержать время и дату клиента (как сообщает их браузер и, соответственно, компьютер, на котором они сидят).Должно быть тривиально включить время сервера в ответ и выполнить некоторые простые математические действия, чтобы угадать точное смещение.