Я хочу, чтобы сервер всегда служил датам в UTC в HTML и JavaScript на клиентском сайте преобразовывал его в пользовательский локальный часовой пояс.
Бонус, если я могу выводить в формате даты локали пользователя.
Я хочу, чтобы сервер всегда служил датам в 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
Этот вопрос довольно старый, поэтому moment.js в то время не существовало, но для новых проектов он упрощает такие задачи много.
Лучше разобрать свою строку даты из UTC следующим образом (создайте ISO-8601 совместимая строка на сервере для получения согласованных результатов во всех браузерах):
var m = moment("2013-02-08T09:30:26Z");
Теперь просто используйте m
в своем приложении, для моментальных действий по умолчанию для момента .js по умолчанию используется локальный часовой пояс. Существует множество способов форматирования значений даты и времени или извлечения их частей.
Вы даже можете отформатировать объект времени в локали пользователей следующим образом:
m.format('LLL') // Returns "February 8 2013 8:30 AM" on en-us
Чтобы преобразовать объект moment.js в другой часовой пояс (т.е. ни локальный, ни UTC), вам понадобится moment.js расширение часового пояса. Эта страница также содержит несколько примеров, она довольно проста в использовании.
Вы можете использовать new Date().getTimezoneOffset()/60
для часового пояса. Существует также метод toLocaleString()
для отображения даты с использованием пользовательской локали.
Здесь весь список: Работа с датами
Вот что я использовал в прошлых проектах:
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 $get
var dateSpn = $get('dataDate');
dateSpn.innerHTML = myDate.localeFormat('F');
После создания объекта даты, здесь фрагмент для преобразования:
Функция принимает объект Date 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);
}
Метод .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');
Я смешиваю ответы до сих пор и добавляю к ним, потому что мне приходилось их читать и дополнительно исследовать какое-то время, чтобы отобразить строку времени даты из db в формате локального часового пояса пользователя.
Строка datetime поступает из файла python/django db в формате: 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: конвертировать в datetime и форматировать его:
var options = { hour: "2-digit", minute: "2-digit" };
var dt = (new Date(str)).toLocaleDateString(defaultlang, options);
В результате (язык браузера en-gb): 05/12/2016, 14:58
Вы можете использовать следующее, которое сообщает о смещении часовой пояс от GMT в минутах:
new Date().getTimezoneOffset();
Примечание: - эта функция возвращает отрицательное число.
Лучшее решение, с которым я столкнулся, - создать [time display = "llll" datetime = "UTC TIME" /] Tags и использовать javascript (jquery) для разбора и отображения его относительно времени пользователя.
http://momentjs.com/ Moment.js
отобразит время красиво.
getTimeZoneOffset() и toLocaleString хороши для работы с базой данных, но если вам нужна поддержка реального времени, посмотрите mde TimeZone.js.
В 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() - в ms, следовательно, x 60 000.
Для преобразования даты в локальную дату используйте метод toLocaleDateString().
var date = (new Date(str)).toLocaleDateString(defaultlang, options);
Чтобы преобразовать время в локальное время, используйте метод toLocaleTimeString().
var time = (new Date(str)).toLocaleTimeString(defaultlang, options);
Не знаю, как сделать локаль, но javascript - это клиентская технология.
usersLocalTime = new Date();
будет иметь в нем время и дату клиента (как сообщается в их браузере, а также по расширению компьютера, на котором они сидят). Это должно быть тривиально включать время сервера в ответ и сделать некоторую простую математику, чтобы угадать смещение.