Как игнорировать часовой пояс пользователя и дату силы () использовать определенный часовой пояс



в приложении JS я получаю метку времени (eq. 1270544790922) с сервера (Ajax).



на основе этой метки времени я создаю Date объект с помощью:



var _date = new Date();
_date.setTime(1270544790922);


теперь _date декодированная метка времени в текущем часовом поясе локали пользователя. Я этого не хочу.



Я хотел бы _date преобразовать в метку времени текущее время в городе Хельсинки в Европу (без учета текущего часового пояса пользователя).



как я могу это сделать?

732   6  

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

    Ничего не найдено.