Converter UTC Epoch para data local

275

Eu tenho lutado com isso por um tempo agora. Estou tentando converter época em um objeto de data. A época é enviada para mim no UTC. Sempre que você passa por new Date()uma época, ela assume a época local. Tentei criar um objeto UTC, usando-o setTime()para ajustá-lo à época apropriada, mas o único método que parece útil é que as toUTCString()strings não me ajudam. Se eu passar essa string para uma nova data, ele deve notar que é UTC, mas não.

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

Minha próxima tentativa foi tentar obter a diferença entre a época atual local e a atual UTC, mas também não consegui.

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

Só está me dando diferenças muito pequenas, abaixo de 1000, ou seja, em milissegundos.

Alguma sugestão?

Shane Reustle
fonte
11
O tempo da época é definido como os milissegundos decorridos desde a data de 1970 no UTC . Não existe uma época local! Não tenho certeza se entendi o seu problema.
Chetan S
Talvez o fuso horário no computador esteja incorreto, levando a um valor UTC diferente?
Kijin
2
Você precisa ajustar o relógio para a hora UTC, se quiser 'ver' a hora UTC ao usar toLocaleString (). Meia-noite UTC são 19:00 EST. Se você usar o novo Date (). ToString () em vez de localeString, obterá algo como: 'Fri Jan 07 2011 07:00:00 GMT-0500', que inclui o deslocamento.
Kennebec

Respostas:

467

Eu acho que tenho uma solução mais simples - defina a data inicial para a época e adicione unidades UTC. Digamos que você tenha uma época UTC var armazenada em segundos. Que tal 1234567890. Para converter isso em uma data adequada no fuso horário local:

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 agora é uma data (no meu fuso horário) definida como Fri Feb 13 2009 18:31:30 GMT-0500 (EST)

user1030503
fonte
190
FWIW, objetos Data podem ser inicializados em milissegundos. Portanto, var d = new Date(utcSeconds * 1000)deve produzir o mesmo resultado.
precisa saber é o seguinte
54
var d = new Date(1234567890000)retorna o mesmo resultado
Matjaz Lipus 06/02
11
pensei que talvez outros pudessem obter alguma clareza em alguns pontos: o objeto de data não é definido com um fuso horário "carimbado nele". pense nisso como nada além de um número. esse número é o número de milissegundos desde 1970, 1 de janeiro de UTC, até agora (agora também em UTC). Portanto, sempre que você cria um objeto de data, ele está realmente no UTC nos bastidores. 2. Para exibir essa data, você pode exibi-la como a configuração de localidade (toLocaleString () ou, no UTC (toUTCString ()). Você não precisa converter nada por conta própria. string - contanto que esteja no fuso horário local.
da Bich
2
1234567890000 é tratado da mesma forma 1234567890, aka o problema Y39K ...
muttonUp
1
@muttonUp, com 1000 aplicações múltiplas funcionou. Mas, 'problema Y39K" O Google é não dar qualquer resultado válido Qualquer URL será útil.
P Satish Patro
238

É fácil, new Date()leva apenas milissegundos, por exemplo

new Date(1394104654000)
> Thu Mar 06 2014 06:17:34 GMT-0500 (EST)
djechlin
fonte
6
Agradável! Isso deve ser considerado realmente a resposta aceita.
Nizar B.
Este não trabalho para mim, ele funciona quando você tem timestamp mas com época UTC você tem que utcseconds definidos manualmente, a resposta aceito é a resposta certa
sameerali
12
Esta é uma resposta apropriada. Nova data pode levar milissegundos, portanto, basta multiplicar por 1000: const d = new Date(epoch * 1000).
vinyll
@sameerali Talvez você tenha tido algum problema diferente com seu sistema ou tenha se confundido. Esta resposta é a resposta correta. A definição da época do Unix: número de segundos decorridos desde 1º de janeiro à meia-noite UTC . Basta multiplicar por 1000 para obter o número de milissegundos decorridos.
N
32

E apenas para os logs, fiz isso usando a biblioteca Moment.js , que eu estava usando para formatar de qualquer maneira.

moment.utc(1234567890000).local()
>Fri Feb 13 2009 19:01:30 GMT-0430 (VET)
Gus
fonte
1
O momento é agradável, mas é insano usar uma biblioteca de 1,3 MB para converter apenas uma época em uma data. Não é de admirar que haja tantos aplicativos de nós inchados por aí.
Not2qubit
20

O tempo da época é em segundos a partir de 1º de janeiro de 1970. date.getTime()retorna milissegundos a partir de 1º de janeiro de 1970, então .. se você tiver um carimbo de data / hora da época, converta-o em um carimbo de data / hora do javascript multiplicando por 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
fonte
Estava me perguntando o que diabos estava acontecendo. É muito bom saber que epochTime! == javascriptTime quando se trata de análise de data. Obrigado!
precisa saber é o seguinte
16
 function ToLocalDate (inDate) {
    var date = new Date();
    date.setTime(inDate.valueOf() - 60000 * inDate.getTimezoneOffset());
    return date;
}
chris
fonte
1
Você fez meu dia. TY. Acabei de substituir o sinal de menos por um sinal de mais para o meu trabalho.
Ludovic Kuty
5

Para converter o tempo atual da época em [ms] para um tempo de 24 horas. Pode ser necessário especificar a opção para desativar o formato de 12 horas .

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

2/7/2018, 19:35:24

ou como 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

Nota: O uso en-GBaqui é apenas uma escolha (aleatória) de um lugar usando o formato de 24 horas, não é o seu fuso horário!

not2qubit
fonte
1
Essa é a melhor maneira de obter qualquer tipo de conversão usando o método Date. Obrigado!
SeaWarrior404
A única coisa que eu não gosto com o exposto acima é que ele retorna a data em um formato ambíguo d/m/yyyyou é m/d/yyyy? O direito (mais lógica) maneira de exibir este deve ser: yyyy-mm-dd. Algum comprador?
not2qubit
4

A hora da época (ou seja, a hora da época Unix) é quase sempre o número de segundos que expiraram desde 1º de janeiro de 1970 00:00:00 (hora UTC), não o número de milissegundos que algumas das respostas aqui implicaram.

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

Portanto, se você recebeu um valor de tempo do Unix Epoch, provavelmente será em segundos e será algo parecido 1547035195. Se você deseja tornar esse humano legível em JavaScript, precisa converter o valor em milissegundos e passar esse valor para o Date(value)construtor, por exemplo:

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

Você não precisa executar a d.setUTCMilliseconds(0)etapa da resposta aceita porque o Date(value)construtor JavaScript utiliza um valor UTC em milissegundos (não no horário local).

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

Observe também que você deve evitar o uso do Date(...)construtor que usa uma representação de data e hora da string; isso não é recomendado (consulte o link acima).

garryp
fonte
3

Você está apenas pedindo para converter uma string UTC em uma string "local"? Você poderia fazer:

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
fonte
3

Além da resposta acima por @djechlin

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

converte a hora do EPOCH em data legível por humanos. Apenas não esqueça que o tipo de tempo de EPOCH deve ser um número inteiro.

Sarvar Nishonboev
fonte
3

A solução mais simples que encontrei para isso é:

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

Observe que isso não tem o * 1000final da new Date(timestamp)declaração, pois isso (para mim de qualquer maneira!) Sempre parece indicar a data errada, ou seja, em vez de indicar o ano de 2019, ele indica 51015, portanto, tenha isso em mente.

Rob P
fonte
2

Se você preferir resolver as conversões de data e hora de e para UTC e a hora local sem bibliotecas como moment.js, dê uma olhada na opção abaixo.

Para aplicativos que usam carimbos de data e hora UTC, pode ser necessário mostrar a data no navegador, considerando o fuso horário local e o horário de verão, quando aplicável. Editar uma data em um horário de verão diferente, embora no mesmo fuso horário possa ser complicado.

As extensões Numbere Dateabaixo permitem mostrar e obter datas no fuso horário dos registros de data e hora. Por exemplo, digamos que você esteja em Vancouver, se estiver editando uma data em julho ou dezembro, isso pode significar que você está editando uma data no PST ou PDT.

Eu recomendo que você verifique o snippet de código abaixo para testar esta solução.

Conversões de milissegundos

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;
};

Conversões de datas

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

Uso

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

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

Veja você mesmo

Darlesson
fonte
Esta é a resposta real. Caiu como uma luva para mim. Definir new Date (0) e adicionando milissegundos é o mesmo que new Date (milissegundos)
Jersey_Guy
1

EDITAR

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());

EDIT Fixed

Amjad Masad
fonte
Eu passei por isso no meu segundo exemplo. As diferenças que ele dá-me em qualquer lugar entre 50 e 900, que é em milisegundos (mostrando o tempo durante o processamento do cálculo, não a diferença real)
Shane Reustle
Nenhum deles me ajuda. Estão faltando um método setUTCTime, que seria perfeito: P w3schools.com/jsref/jsref_obj_date.asp
Shane Reustle
Não funciona, pelo menos no Firefox para Ubuntu. O código não deve ser definido como dia / mês / ano após definir a data.
Simon Kozlov
@ Simon Kozlov Na verdade, é uma suposição errada no objeto de data, o setDate e o getDate se referem ao dia do mês, e o problema é que eu usei funções como (setUTCDay) que não existem, surpreso por ter sido aceito!
Amjad Masad
@AmjadMasad Sua resposta seria mais útil se você também mostrar a saída esperada.
Not2qubit
0

Considerando, você tem epoch_timedisponível,

// 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
fonte
0

@ Ammad, boa ideia, mas uma melhor implementação seria:

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
fonte
-1

Primeiro converta-o em String e substitua o texto do fuso horário.

function convertUnixTime(time) {
  return new Date(time*1000).toString().replace("GMT+0530 (Sri Lanka Standard Time)","");
}
Robot Boy
fonte