Конвертировать UTC Epoch в местную дату

275

Я боролся с этим немного сейчас. Я пытаюсь преобразовать эпоху в объект даты. Эпоха отправлена ​​мне в UTC. Всякий раз, когда вы проходите new Date()эпоху, это предполагает, что это локальная эпоха. Я попытался создать объект UTC, а затем использовать его, setTime()чтобы приспособить его к нужной эпохе, но единственный метод, который кажется полезным, это то, что toUTCString()строки не помогают мне. Если я передам эту строку в новую дату, он должен заметить, что это UTC, но это не так.

new Date( new Date().toUTCString() ).toLocaleString()

Моя следующая попытка состояла в том, чтобы попытаться понять разницу между локальной текущей эпохой и текущей UTC, но я также не смог этого понять.

new Date( new Date().toUTCString() ).getTime() - new Date().getTime()

Это только дает мне очень маленькие различия, до 1000, что в миллисекундах.

Какие-либо предложения?

Шейн Рустл
источник
11
Время эпохи определяется как прошедшие миллисекунды с даты 1970 года в UTC . Нет такой вещи как местная эпоха! Не уверен, что понимаю вашу проблему.
Четан С
Может быть, часовой пояс на компьютере неправильный, что приводит к другому значению UTC?
Киджин
2
Вы должны установить часы на время UTC, если вы хотите «видеть» время UTC при использовании toLocaleString (). Полночь UTC - 7 вечера по восточному поясному времени. Если вы используете новую Date (). ToString () вместо localeString, вы получите что-то вроде: «Пт Ян 07 2011 07:00:00 GMT-0500», который включает смещение.
Кеннебек

Ответы:

467

Я думаю, что у меня есть более простое решение - установить начальную дату для эпохи и добавить единицы измерения UTC. Скажем, у вас есть переменная эпохи UTC, сохраненная в секундах. Как насчет того 1234567890. Чтобы преобразовать это в правильную дату в местном часовом поясе:

var utcSeconds = 1234567890;
var d = new Date(0); // The 0 there is the key, which sets the date to the epoch
d.setUTCSeconds(utcSeconds);

d теперь дата (в моем часовом поясе) установлена ​​на Fri Feb 13 2009 18:31:30 GMT-0500 (EST)

user1030503
источник
190
FWIW, объекты Date могут быть инициализированы за миллисекунды. Итак, var d = new Date(utcSeconds * 1000)должен дать тот же результат.
kurttheviking
54
var d = new Date(1234567890000)возвращает тот же результат
Matjaz Lipus
11
Я подумал, что, возможно, другие могли бы получить некоторую ясность из пары моментов: объект даты не устанавливается с часовым поясом, «отпечатанным в нем». думать об этом как о чем-то, кроме числа. это число равно количеству миллисекунд с 1970 года по 1 января UTC и по настоящее время (в настоящее время также в UTC). Таким образом, всякий раз, когда вы создаете объект даты, он действительно находится в UTC за кулисами. 2. Чтобы отобразить эту дату, вы можете отобразить ее как настройку языкового стандарта (toLocaleString () или в UTC (toUTCString ()). Вам не нужно ничего преобразовывать самостоятельно. Создайте с помощью utc millisec, все хорошо. Создайте с помощью Строка - до тех пор, пока она находится в местном часовом поясе.
Да Бич
2
1234567890000 обрабатывается так же, как 1234567890, иначе проблема Y39K ...
muttonUp
1
@muttonUp, с 1000 мультитропликации это сработало. Но «проблема Y39K» Google не дает никакого действительного результата. Любой URL будет полезен
P Satish Patro
239

Это просто, new Date()просто занимает миллисекунды, например

new Date(1394104654000)
> Thu Mar 06 2014 06:17:34 GMT-0500 (EST)
djechlin
источник
6
Хороший! Это должно рассматриваться как принятый ответ на самом деле.
Низар Б.
Этот не работает для меня, он работает, когда у вас есть временная метка, но в эпоху utc вы должны вручную установить utcseconds, правильный ответ
sameerali
12
Это правильный ответ. Новая дата может занять миллисекунды, поэтому просто умножить на 1000: const d = new Date(epoch * 1000).
Винилл
@ sameerali Возможно, у вас были другие проблемы с вашей системой, или вы запутались. Этот ответ является правильным ответом. Определение эпохи Unix: количество секунд, прошедших с полуночи первого января UTC . Просто умножьте на 1000, чтобы получить количество прошедших миллисекунд.
Вскоре
32

И только для журналов я сделал это с помощью библиотеки Moment.js , которую я в любом случае использовал для форматирования.

moment.utc(1234567890000).local()
>Fri Feb 13 2009 19:01:30 GMT-0430 (VET)
Гас
источник
1
Момент хорош, но безумно использовать 1,3-мегабайтную библиотеку, чтобы просто конвертировать одну эпоху в дату. Неудивительно, что существует так много раздутых узловых приложений.
not2qubit
20

Время эпохи в секундах с 1 января 1970 года. date.getTime()Возвращает миллисекунды с 1 января 1970 года, поэтому ... если у вас есть отметка времени эпохи, преобразуйте ее в метку времени javascript, умножив ее на 1000.

   function epochToJsDate(ts){
        // ts = epoch timestamp
        // returns date obj
        return new Date(ts*1000);
   }

   function jsDateToEpoch(d){
        // d = javascript date obj
        // returns epoch timestamp
        return (d.getTime()-d.getMilliseconds())/1000;
   }
logic8
источник
Интересно, что случилось. Очень приятно знать, что epochTime! == javascriptTime, когда дело доходит до парсинга. Спасибо!
GrayedFox
16
 function ToLocalDate (inDate) {
    var date = new Date();
    date.setTime(inDate.valueOf() - 60000 * inDate.getTimezoneOffset());
    return date;
}
Крис
источник
1
Вы сделали мой день. TY. Я просто заменил знак минус на знак плюс для моей работы.
Людовик Куты
5

Чтобы преобразовать текущее время эпохи в [мс] в 24-часовое время. Возможно, вам потребуется указать опцию отключения 12-часового формата.

$ node.exe -e "var date = new Date(Date.now()); console.log(date.toLocaleString('en-GB', { hour12:false } ));"

2/7/2018, 19:35:24

или как JS:

var date = new Date(Date.now()); 
console.log(date.toLocaleString('en-GB', { hour12:false } ));
// 2/7/2018, 19:35:24

console.log(date.toLocaleString('en-GB', { hour:'numeric', minute:'numeric', second:'numeric', hour12:false } ));
// 19:35:24

Примечание: использование en-GBздесь, это просто (случайный) выбор места с использованием 24-часового формата, это не ваш часовой пояс!

not2qubit
источник
1
Это лучший способ получить любой тип конверсии из метода Date. Спасибо!
SeaWarrior404
Единственное, что мне не нравится в вышесказанном, это то, что он возвращает дату в таком неоднозначном формате d/m/yyyyили это так m/d/yyyy? Право (наиболее логичным) способ отображения это должно быть: yyyy-mm-dd. Любой берущий?
not2qubit
4

Время эпохи (т. Е. Время эпохи Unix) - это почти всегда количество секунд , истекших с 1 января 1970 года 00:00:00 (время UTC), а не количество миллисекунд, на которое указывают некоторые ответы.

https://en.wikipedia.org/wiki/Unix_time

Следовательно, если вы получили значение времени Unix Epoch, оно, вероятно, будет в секундах и будет выглядеть примерно так 1547035195. Если вы хотите, чтобы этот человек читался в JavaScript, вам нужно преобразовать значение в миллисекунды и передать это значение в Date(value)конструктор, например:

const unixEpochTimeMS = 1547035195 * 1000;
const d = new Date(unixEpochTimeMS);
// Careful, the string output here can vary by implementation...
const strDate = d.toLocaleString();

Вам не нужно делать d.setUTCMilliseconds(0)шаг в принятом ответе, потому что Date(value)конструктор JavaScript принимает значение UTC в миллисекундах (не по местному времени).

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date#Syntax

Также обратите внимание, что вам следует избегать использования Date(...)конструктора, который принимает строковое представление даты-времени, это не рекомендуется (см. Ссылку выше).

garryp
источник
3

Вы просто просите преобразовать строку UTC в "локальную" строку? Вы могли бы сделать:

var utc_string = '2011-09-05 20:05:15';
var local_string = (function(dtstr) {
    var t0 = new Date(dtstr);
    var t1 = Date.parse(t0.toUTCString().replace('GMT', ''));
    var t2 = (2 * t0) - t1;
    return new Date(t2).toString();
})(utc_string);
ZagNut
источник
3

Дополнение к приведенному выше ответу @djechlin

d = '1394104654000';
new Date(parseInt(d));

преобразует время EPOCH в удобочитаемую дату Только не забывайте, что тип времени EPOCH должен быть целым числом.

Сарвар Нишонбоев
источник
3

Самое простое решение, которое я нашел, это:

var timestamp = Date.now(), // returns milliseconds since epoch time
    normalisedTime = new Date(timestamp);

Обратите внимание, что * 1000в конце new Date(timestamp)утверждения нет этого, поскольку это (во всяком случае, для меня!) Всегда выдает неверную дату, то есть вместо указания 2019-го года это 51015, так что просто имейте это в виду.

Роб П
источник
2

Если вы предпочитаете разрешать временные метки и преобразования дат из и в UTC и местное время без библиотек, таких как moment.js, взгляните на опцию ниже.

Для приложений, использующих метки времени UTC, вам может потребоваться отобразить дату в браузере, учитывая местный часовой пояс и переход на летнее время, когда это применимо. Редактирование даты в другое летнее время, даже если в том же часовом поясе может быть сложно.

Расширения Numberи Dateниже позволяют отображать и получать даты в часовом поясе временных меток. Например, предположим, что вы находитесь в Ванкувере, если вы редактируете дату в июле или декабре, это может означать, что вы редактируете дату в PST или PDT.

Я рекомендую вам проверить фрагмент кода ниже, чтобы проверить это решение.

Преобразования из миллисекунд

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

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

    return value;
};

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

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

    return value;
};

Конверсии из дат

Date.prototype.getUTCTime = function () {
    return this.getTime() - (this.getTimezoneOffset() * 60000);
};

использование

// Adds the timezone and daylight savings if applicable
(1499670000000).toLocalDate();

// Eliminates the timezone and daylight savings if applicable
new Date(2017, 6, 10).getUTCTime();

Убедитесь сами

Darlesson
источник
Это фактический ответ. Работал как шарм для меня. Установка новой даты (0) и добавление миллисекунд совпадает с новой датой (миллисекунды)
Jersey_Guy
1

РЕДАКТИРОВАТЬ

var utcDate = new Date(incomingUTCepoch);
var date = new Date();
date.setUTCDate(utcDate.getDate());
date.setUTCHours(utcDate.getHours());
date.setUTCMonth(utcDate.getMonth());
date.setUTCMinutes(utcDate.getMinutes());
date.setUTCSeconds(utcDate.getSeconds());
date.setUTCMilliseconds(utcDate.getMilliseconds());

Редактировать исправлено

Амджад Масад
источник
Я прошел через это во втором примере. Различия, которые он мне дает, находятся где-то между 50 и 900, то есть в миллисекундах (показывая время во время обработки вычисления, а не фактическую разницу)
Шейн Рустл
Никто из них не помогает мне. В них отсутствует метод setUTCTime, который был бы идеальным: P w3schools.com/jsref/jsref_obj_date.asp
Шейн Рустл
Не работает, по крайней мере, в Firefox для Ubuntu. Код не должен устанавливать день / месяц / год после того, как он устанавливает дату.
Симон Козлов
@Simon Kozlov На самом деле это неверное предположение в объекте даты, setDate и getDate ссылаются на день в месяце, и проблема в том, что я использовал такие функции, как (setUTCDay), которые не существуют, удивлен, что их приняли !!
Амжад Масад
@AmjadMasad Ваш ответ будет более полезным, если вы также покажете ожидаемый результат.
not2qubit
0

Учитывая, что у вас есть в epoch_timeналичии,

// for eg. epoch_time = 1487086694.213
var date = new Date(epoch_time * 1000); // multiply by 1000 for milliseconds
var date_string = date.toLocaleString('en-GB');  // 24 hour format
apurva.nandan
источник
0

@ Амджад, хорошая идея, но лучшая реализация:

Date.prototype.setUTCTime = function(UTCTimestamp) {
    var UTCDate = new Date(UTCTimestamp);
    this.setUTCFullYear(UTCDate.getFullYear(), UTCDate.getMonth(), UTCDate.getDate());
    this.setUTCHours(UTCDate.getHours(), UTCDate.getMinutes(), UTCDate.getSeconds(), UTCDate.getMilliseconds());
    return this.getTime();
}
WALF
источник
-1

Сначала преобразуйте его в строку, а затем замените текст часового пояса.

function convertUnixTime(time) {
  return new Date(time*1000).toString().replace("GMT+0530 (Sri Lanka Standard Time)","");
}
Робот мальчик
источник