Преобразование миллисекунд в объект даты UTC с часовым поясом UTC

Я пытаюсь преобразовать миллисекунды в объект даты UTC, как показано ниже:

var tempDate = new Date(1465171200000);
// --> tempDate = Mon Jun 06 2016 05:30:00 **GMT+0530 (India Standard Time)** {}

var _utcDate = new Date(tempDate.getUTCFullYear(), tempDate.getUTCMonth(), tempDate.getUTCDate(),  tempDate.getUTCHours(), tempDate.getUTCMinutes(), tempDate.getUTCSeconds());
//--> _utcDate = Mon Jun 06 2016 00:00:00 **GMT+0530 (India Standard Time)** {}

Время сбрасывается на время UTC, но часовой пояс по-прежнему идет как GMT+0530 (стандартное время Индии). Есть ли какой-нибудь надежный подход для преобразования миллисекунд в объект даты UTC с часовым поясом UTC?


person Anand Mohan Singh    schedule 06.06.2017    source источник
comment
Почему вы делаете два объекта даты? Чтобы получить строку даты UTC, используйте tempDate.toUTCString()   -  person evolutionxbox    schedule 06.06.2017
comment
@evolutionxbox - на самом деле tempDate.toUTCString() преобразует объект даты в строку, не сможет выполнять над ним дальнейшие операции с датами.   -  person Anand Mohan Singh    schedule 06.06.2017


Ответы (3)


Цитата из этот ответ (который я предлагаю вам прочитать полностью):

В самом объекте Date не хранится часовой пояс или строковый формат. При использовании различных функций объекта Date к внутреннему представлению применяется локальный часовой пояс компьютера.

Поскольку часовой пояс не хранится в объекте Date, установить его невозможно.

Я вижу два варианта:

первый — использовать библиотеку (как предложено в ответе выше). Сейчас довольно популярен Moment.js.

второй (чистый JavaScript — если это жизнеспособное решение в вашем контексте):

Сделайте «математику времени» в вашем местном часовом поясе.

Когда вы будете готовы переключиться на UTC, используйте метод toUTCString().

Конечно, вы получите строку, так как это позволит вам сохранить часовой пояс до значения даты и времени.

Поскольку с этого момента вы не сможете манипулировать датой и временем как объектом Date, это должен быть последний шаг.

var tempDate = new Date(1465171200000);
// Mon Jun 06 2016 05:30:00 GMT+0530

// Do your date time math here
// using the Date object's methods

var utcDateAsString = tempDate.toUTCString();
// Mon Jun 06 2016 00:00:00 GMT
person Paolo    schedule 06.06.2017
comment
Встроенный синтаксический анализатор требуется (начиная с ECMAScript 2015?) для правильного анализа любых связанных методов toString и toUTCString, но только для каждой реализации. - person RobG; 07.06.2017

Ты говоришь:

Время сбрасывается на время UTC, но часовой пояс по-прежнему идет как GMT+0530 (стандартное время Индии). Есть ли какой-нибудь надежный подход для преобразования миллисекунд в объект даты UTC с часовым поясом UTC?

Но я думаю, что вы неправильно понимаете, что происходит. Когда вы передаете число конструктору Date, как в:

new Date(1465171200000)

предполагается, что это миллисекунды с эпохи ECMAScript (1970-01-01T00:00:00Z), поэтому объект Date создается с этим значением в качестве внутреннего значения времени. Таким образом, объекты Date по своей сути являются UTC.

Когда вы записываете это в строку, внутри создается удобочитаемая строка даты на основе настройки часового пояса хоста, поэтому вы видите дату для GMT+0530 (это настройка часового пояса вашей хост-системы). Сам объект Date не имеет часового пояса, это всегда UTC.

Когда вы затем используете значения UTC для создания «локальной» даты, используя:

new Date(tempDate.getUTCFullYear(), tempDate.getUTCMonth(), ...)

затем часовой пояс хоста используется для создания значения времени UTC, эквивалентного «местной» дате для связанных значений. Вы фактически вычли смещение вашего часового пояса из исходного значения времени, поэтому теперь оно представляет другой момент времени. Вы можете получить точно такой же результат, выполнив:

var d = new Date(1465171200000);
d.setMinutes(d.getMintues() + d.getTimezoneOffset());

который просто показывает немного более четко, что происходит. Обратите внимание, что смещения часовых поясов ECMAScript указаны в минутах и ​​имеют противоположное UTC значение, то есть они отрицательные (-) для востока и положительные (+) для запада. Таким образом, смещение UTC+05:30 представляется как -330, и вам нужно добавить его, чтобы «сдвинуть» дату, а не вычесть ее.

var tempDate = new Date(1465171200000);

var _utcDate = new Date(tempDate.getUTCFullYear(), tempDate.getUTCMonth(), tempDate.getUTCDate(),  tempDate.getUTCHours(), tempDate.getUTCMinutes(), tempDate.getUTCSeconds());

console.log('Direct conversion to Date\ntempDate: ' + tempDate.toString());
console.log('Adjusted using UTC methods\n_utcDate: ' + _utcDate.toString());

tempDate.setMinutes(tempDate.getMinutes() + tempDate.getTimezoneOffset());
console.log('Adjusted using timezoneOffset\ntempDate: ' + tempDate.toString());

Однако я не могу понять, почему вы хотите сделать вышеперечисленное. 1465171200000 представляет определенный момент времени (2016-06-06T00:00:00Z), его настройка для каждого часового пояса клиента означает, что он представляет другой момент времени для каждого клиента с разным смещением часового пояса.

person RobG    schedule 06.06.2017

Если вы создаете Date из Number, учитывается местный часовой пояс. Но если вы хотите увидеть, что будет означать метка времени с часами, скорректированными для UTC, вы можете использовать помощник как таковой:

Number.prototype.toUTCDate = function () {
    var value = new Date(this);

    value.setHours(value.getHours() - (value.getTimezoneOffset() / 60));

    return value;
};

Использование будет:

var date = (1465171200000).toUTCDate();
person Darlesson    schedule 02.08.2017