Как игнорировать часовой пояс пользователя и дату силы () использовать определенный часовой пояс
в приложении JS я получаю метку времени (eq. 1270544790922) с сервера (Ajax).
на основе этой метки времени я создаю Date объект с помощью:
var _date = new Date();
_date.setTime(1270544790922);
теперь _date декодированная метка времени в текущем часовом поясе локали пользователя. Я этого не хочу.
Я хотел бы _date преобразовать в метку времени текущее время в городе Хельсинки в Европу (без учета текущего часового пояса пользователя).
как я могу это сделать?
6 ответов:
базовое значение объекта даты фактически находится в UTC. Чтобы доказать это, обратите внимание, что если вы наберете
new Date(0)вы увидите что-то вроде:Wed Dec 31 1969 16:00:00 GMT-0800 (PST). 0 рассматривается как 0 в GMT, но.toString()метод показывает местное время.большое Примечание, UTC означает универсальная код времени. Текущее время прямо сейчас в 2 разных местах - это один и тот же UTC, но выход может быть отформатирован по-разному.
что нам здесь нужно форматирование
var _date = new Date(1270544790922); // outputs > "Tue Apr 06 2010 02:06:30 GMT-0700 (PDT)", for me _date.toLocaleString('fi-FI', { timeZone: 'Europe/Helsinki' }); // outputs > "6.4.2010 klo 12.06.30" _date.toLocaleString('en-US', { timeZone: 'Europe/Helsinki' }); // outputs > "4/6/2010, 12:06:30 PM"это работает, но.... вы не можете использовать какие-либо другие методы даты для своих целей, поскольку они описывают часовой пояс пользователя. Вам нужен объект даты, связанный с часовым поясом Хельсинки. На данный момент Вы можете использовать некоторую стороннюю библиотеку (я рекомендую это) или взломать объект даты, чтобы вы могли использовать большинство его методов.
Вариант 1-третья сторона, как время-часовой пояс
moment(1270544790922).tz('Europe/Helsinki').format('YYYY-MM-DD HH:mm:ss') // outputs > 2010-04-06 12:06:30 moment(1270544790922).tz('Europe/Helsinki').hour() // outputs > 12это выглядит намного более элегантным, чем то, что мы собираемся делать дальше.
Вариант 2-Взломать объект даты
var currentHelsinkiHoursOffset = 2; // sometimes it is 3 var date = new Date(1270544790922); var helsenkiOffset = currentHelsinkiHoursOffset*60*60000; var userOffset = _date.getTimezoneOffset()*60000; // [min*60000 = ms] var helsenkiTime = new Date(date.getTime()+ helsenkiOffset + userOffset); // Outputs > Tue Apr 06 2010 12:06:30 GMT-0700 (PDT)он все еще думает, что это GMT-0700 (PDT), но если вы не слишком пристально смотрите, вы можете ошибиться в этом для объекта даты, который полезен для ваших целей.
Я как раз пропустил часть. Вы должны быть в состоянии определить
currentHelsinkiOffset. Если вы можете использоватьdate.getTimezoneOffset()на стороне сервера, или просто используйте некоторые операторы if для описания того, когда произойдет изменение часового пояса, что должно решить вашу проблему.вывод - я думаю, что специально для этой цели вы должны использовать современная библиотека как время-часовой пояс.
чтобы учесть миллисекунды и часовой пояс пользователя, используйте следующее:
var _userOffset = _date.getTimezoneOffset()*60*1000; // user's offset time var _centralOffset = 6*60*60*1000; // 6 for central time - use whatever you need _date = new Date(_date.getTime() - _userOffset + _centralOffset); // redefine variable
у меня есть подозрение, что ответ не дает правильного результата. В своем вопросе Аскер хочет конвертировать метку времени с сервера на текущее время в Хеллсинки без учета текущего часового пояса пользователя.
это к тому, что часовой пояс пользователя может быть что-либо, поэтому мы не можем доверять ему.
если например. отметка времени 1270544790922 и у нас есть функция:
var _date = new Date(); _date.setTime(1270544790922); var _helsenkiOffset = 2*60*60;//maybe 3 var _userOffset = _date.getTimezoneOffset()*60*60; var _helsenkiTime = new Date(_date.getTime()+_helsenkiOffset+_userOffset);когда житель Нью-Йорка посещает страницу, предупреждение(_helsenkiTime) отпечатки пальцев:
Tue Apr 06 2010 05:21:02 GMT-0400 (EDT)и когда Финландер посещает страницу, alert (_helsenkiTime) печатает:
Tue Apr 06 2010 11:55:50 GMT+0300 (EEST)таким образом, функция корректна только в том случае, если посетитель страницы имеет целевой часовой пояс (Европа/Хельсинки) в своем компьютере, но терпит неудачу почти во всех других частях мира. И поскольку метка времени сервера обычно является меткой времени UNIX, которая по определению находится в UTC, количество секунд с момента эпохи Unix (1 января 1970 00: 00: 00 GMT), мы не можем определить DST или non-DST из отметка времени.
таким образом, решение состоит в том, чтобы игнорировать текущий часовой пояс пользователя и реализовать некоторый способ вычисления смещения UTC, независимо от того, находится ли дата в DST или нет. Javascript не имеет собственного метода для определения истории перехода DST другого часового пояса, чем текущий часовой пояс пользователя. Мы можем достичь этого наиболее просто с помощью сценария на стороне сервера, потому что у нас есть легкий доступ к базе данных часовых поясов сервера со всей историей переходов всех часовых поясов.
но если у вас есть нет доступа к базе данных часового пояса сервера (или любого другого сервера), а метка времени находится в UTC, вы можете получить аналогичную функциональность, жестко кодируя правила DST в Javascript.
для покрытия датами в годах 1998 - 2099 в Европа/Хельсинки вы можете использовать следующую функцию (jsfiddled):
function timestampToHellsinki(server_timestamp) { function pad(num) { num = num.toString(); if (num.length == 1) return "0" + num; return num; } var _date = new Date(); _date.setTime(server_timestamp); var _year = _date.getUTCFullYear(); // Return false, if DST rules have been different than nowadays: if (_year<=1998 && _year>2099) return false; // Calculate DST start day, it is the last sunday of March var start_day = (31 - ((((5 * _year) / 4) + 4) % 7)); var SUMMER_start = new Date(Date.UTC(_year, 2, start_day, 1, 0, 0)); // Calculate DST end day, it is the last sunday of October var end_day = (31 - ((((5 * _year) / 4) + 1) % 7)) var SUMMER_end = new Date(Date.UTC(_year, 9, end_day, 1, 0, 0)); // Check if the time is between SUMMER_start and SUMMER_end // If the time is in summer, the offset is 2 hours // else offset is 3 hours var hellsinkiOffset = 2 * 60 * 60 * 1000; if (_date > SUMMER_start && _date < SUMMER_end) hellsinkiOffset = 3 * 60 * 60 * 1000; // Add server timestamp to midnight January 1, 1970 // Add Hellsinki offset to that _date.setTime(server_timestamp + hellsinkiOffset); var hellsinkiTime = pad(_date.getUTCDate()) + "." + pad(_date.getUTCMonth()) + "." + _date.getUTCFullYear() + " " + pad(_date.getUTCHours()) + ":" + pad(_date.getUTCMinutes()) + ":" + pad(_date.getUTCSeconds()); return hellsinkiTime; }примеры использования:
var server_timestamp = 1270544790922; document.getElementById("time").innerHTML = "The timestamp " + server_timestamp + " is in Hellsinki " + timestampToHellsinki(server_timestamp); server_timestamp = 1349841923 * 1000; document.getElementById("time").innerHTML += "<br><br>The timestamp " + server_timestamp + " is in Hellsinki " + timestampToHellsinki(server_timestamp); var now = new Date(); server_timestamp = now.getTime(); document.getElementById("time").innerHTML += "<br><br>The timestamp is now " + server_timestamp + " and the current local time in Hellsinki is " + timestampToHellsinki(server_timestamp);и это печатает следующее независимо от часового пояса пользователя:
The timestamp 1270544790922 is in Hellsinki 06.03.2010 12:06:30 The timestamp 1349841923000 is in Hellsinki 10.09.2012 07:05:23 The timestamp is now 1349853751034 and the current local time in Hellsinki is 10.09.2012 10:22:31конечно, если вы можете возвращайте метку времени в форме, в которой смещение (DST или не DST) уже добавлено к метке времени на сервере, вам не нужно вычислять его на стороне клиента, и вы можете значительно упростить функцию. Но не забывайте использовать timezoneOffset (), потому что тогда вам придется иметь дело с пользовательским часовым поясом, и это не желаемое поведение.
просто еще один подход
function parseTimestamp(timestampStr) { return new Date(new Date(timestampStr).getTime() + (new Date().getTimezoneOffset() * 60 * 1000)); }; //Sun Jan 01 2017 12:00:00 var timestamp = 1483272000000; date = parseTimestamp(timestamp); document.write(date);Ура!
предполагая, что вы получите метку времени в Хельсинки, я бы создал объект даты, установленный в полночь 1 января 1970 UTC (для игнорирования настроек локального часового пояса браузера). Затем просто добавьте необходимое количество миллисекунд к нему.
var _date = new Date( Date.UTC(1970, 0, 1, 0, 0, 0, 0) ); _date.setUTCMilliseconds(1270544790922); alert(_date); //date shown shifted corresponding to local time settings alert(_date.getUTCFullYear()); //the UTC year value alert(_date.getUTCMonth()); //the UTC month value alert(_date.getUTCDate()); //the UTC day of month value alert(_date.getUTCHours()); //the UTC hour value alert(_date.getUTCMinutes()); //the UTC minutes valueследите позже, чтобы всегда запрашивать значения UTC из объекта даты. Таким образом, пользователи будут видеть одни и те же значения даты независимо от локальных настроек. В противном случае значения дат будут смещены в соответствии с локальными параметры времени.
вы могли бы использовать
setUTCMilliseconds()var _date = new Date(); _date.setUTCMilliseconds(1270544790922);
Comments