Convertir UTC Epoch a fecha local

275

He estado luchando con esto por un tiempo ahora. Estoy tratando de convertir época en un objeto de fecha. La época me fue enviada en UTC. Cada vez que pasa new Date()una época, se supone que es una época local. Intenté crear un objeto UTC, luego lo usé setTime()para ajustarlo a la época adecuada, pero el único método que parece útil es toUTCString()y las cadenas no me ayudan. Si paso esa cadena a una nueva fecha, debería notar que es UTC, pero no lo hace.

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

Mi siguiente intento fue tratar de obtener la diferencia entre la época actual local y la época actual UTC, pero tampoco pude conseguir eso.

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

Solo me da diferencias muy pequeñas, menos de 1000, que está en milisegundos.

¿Alguna sugerencia?

Shane Reustle
fuente
11
El tiempo de época se define como los milisegundos transcurridos desde la fecha de 1970 en UTC . ¡No existe una época local! No estoy seguro de entender tu problema.
Chetan S
¿Quizás la zona horaria en la computadora es incorrecta, lo que lleva a un valor UTC diferente?
kijin
2
Debe configurar su reloj a la hora UTC, si desea 'ver' la hora UTC cuando usa toLocaleString (). La medianoche UTC es a las 7 p.m. EST. Si usa la nueva Fecha (). ToString () en lugar de localeString, obtendría algo como: 'Vie 07 Ene 2011 07:00:00 GMT-0500', que incluye el desplazamiento.
Kennebec

Respuestas:

467

Creo que tengo una solución más simple: establecer la fecha inicial de la época y agregar unidades UTC. Digamos que tiene una var. De época UTC almacenada en segundos. ¿Qué tal 1234567890. Para convertir eso a una fecha adecuada en la zona horaria 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 ahora es una fecha (en mi zona horaria) establecida en Fri Feb 13 2009 18:31:30 GMT-0500 (EST)

usuario1030503
fuente
190
FWIW, los objetos de fecha se pueden inicializar con milisegundos. Por lo tanto, var d = new Date(utcSeconds * 1000)debería producir el mismo resultado.
kurttheviking
54
var d = new Date(1234567890000)devuelve el mismo resultado
Matjaz Lipus
11
pensé que quizás otros podrían obtener algo de claridad de un par de puntos: el objeto de fecha no se configura con una zona horaria "estampada en él". Piense en ello como nada más que un número. ese número es el número de milisegundos desde 1970 ene 1 UTC, hasta ahora (ahora también en UTC). Entonces, cada vez que crea un objeto de fecha, realmente está en UTC detrás de escena. 2. Para mostrar esa fecha, puede mostrarla como la configuración regional (toLocaleString (), o, en UTC (toUTCString ()). No necesita convertir nada usted mismo. Construya con utc millisec, todo bien. Construya con string - tanto tiempo ya que está en la zona horaria local.
da Bich
2
1234567890000 se trata igual que 1234567890, también conocido como el problema Y39K ...
muttonUp
1
@muttonUp, con 1000 aplicaciones múltiples funcionó. Pero, 'problema Y39K ", Google no está dando ningún resultado válido. Cualquier URL será útil
P Satish Patro
239

Es fácil, new Date()solo toma milisegundos, por ej.

new Date(1394104654000)
> Thu Mar 06 2014 06:17:34 GMT-0500 (EST)
djechlin
fuente
66
¡Buena esa! Esto debería considerarse como la respuesta aceptada realmente.
Nizar B.
Este no funcionó para mí, funciona cuando tienes una marca de tiempo, pero con utc epoch debes configurar utcseconds manualmente, la respuesta de aceptación es la respuesta correcta
sameerali
12
Esta es una respuesta apropiada. Nueva fecha puede tomar milisegundos, por lo tanto, simplemente se multiplica por 1000: const d = new Date(epoch * 1000).
vinil
@sameerali Quizás tuvo un problema diferente con su sistema o se confundió. Esta respuesta es la respuesta correcta. La definición de la época de Unix: número de segundos transcurridos desde el 1 de enero a la medianoche UTC . Simplemente multiplique por 1000 para obtener el número de milisegundos transcurridos.
nalply
32

Y solo para los registros, hice esto usando la biblioteca Moment.js , que estaba usando para formatear de todos modos.

moment.utc(1234567890000).local()
>Fri Feb 13 2009 19:01:30 GMT-0430 (VET)
Gus
fuente
1
El momento es agradable, pero es una locura usar una biblioteca de 1.3 MB para convertir una época en una fecha. No es de extrañar que haya tantas aplicaciones de nodo hinchado por ahí.
not2qubit
20

El tiempo de época es en segundos desde el 1 de enero de 1970. date.getTime()devuelve milisegundos desde el 1 de enero de 1970, por lo tanto, si tiene una marca de tiempo de época, conviértala en una marca de tiempo de JavaScript multiplicándola 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;
   }
lógica8
fuente
Me preguntaba qué demonios estaba pasando. Muy bueno saber que epochTime! == javascriptTime cuando se trata de análisis de fechas. ¡Gracias!
GrayedFox
16
 function ToLocalDate (inDate) {
    var date = new Date();
    date.setTime(inDate.valueOf() - 60000 * inDate.getTimezoneOffset());
    return date;
}
Chris
fuente
1
Me has alegrado el día. TY. Acabo de reemplazar el signo menos por un signo más para mi trabajo.
Ludovic Kuty
5

Para convertir el tiempo de época actual en [ms] a un tiempo de 24 horas. Es posible que deba especificar la opción para deshabilitar el 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

o 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: El uso de en-GBaquí, es solo una elección (aleatoria) de un lugar usando el formato de 24 horas, ¡no es su zona horaria!

not2qubit
fuente
1
Esta es la mejor manera de obtener cualquier tipo de conversión del método Fecha. ¡Gracias!
SeaWarrior404
Lo único que no me gusta con lo anterior, es que devuelve la fecha en ese formato ambiguo d/m/yyyyo no m/d/yyyy? La manera correcta (más lógica) para mostrar este debe ser: yyyy-mm-dd. ¿Ningún arrendatario?
not2qubit
4

El tiempo de la época (es decir, el tiempo de la época de Unix) es casi siempre el número de segundos que han expirado desde el 1 de enero de 1970 a las 00:00:00 (hora UTC), no el número de milisegundos que algunas de las respuestas aquí han implicado.

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

Por lo tanto, si se le ha dado un valor de tiempo de Unix Epoch, probablemente será en segundos y tendrá un aspecto similar 1547035195. Si desea que este humano sea legible en JavaScript, debe convertir el valor a milisegundos y pasar ese valor al Date(value)constructor, por ejemplo:

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

No necesita realizar el d.setUTCMilliseconds(0)paso en la respuesta aceptada porque el Date(value)constructor de JavaScript toma un valor UTC en milisegundos (no una hora local).

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

También tenga en cuenta que debe evitar usar el Date(...)constructor que toma una representación de fecha y hora de cadena, esto no se recomienda (consulte el enlace anterior).

garryp
fuente
3

¿Solo está pidiendo convertir una cadena UTC en una cadena "local"? Podrías hacerlo:

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

Además de la respuesta anterior por @djechlin

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

convierte el tiempo EPOCH en una fecha legible para humanos. Simplemente no olvide que el tipo de tiempo EPOCH debe ser un número entero.

Sarvar Nishonboev
fuente
3

La solución más simple que he encontrado para esto es:

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

Tenga en cuenta que esto no tiene el * 1000final de la new Date(timestamp)declaración, ya que esto (¡para mí de todos modos!) Siempre parece dar una fecha incorrecta, es decir, en lugar de dar el año 2019, da el año como 51015, así que tenga eso en cuenta.

Rob P
fuente
2

Si prefiere resolver las marcas de tiempo y las conversiones de fechas desde y hacia UTC y hora local sin bibliotecas como moment.js, eche un vistazo a la opción a continuación.

Para las aplicaciones que usan marcas de tiempo UTC, es posible que deba mostrar la fecha en el navegador teniendo en cuenta la zona horaria local y el horario de verano cuando corresponda. Editar una fecha que está en un horario de verano diferente, aunque en la misma zona horaria puede ser complicado.

Las extensiones Numbery a Datecontinuación le permiten mostrar y obtener fechas en la zona horaria de las marcas de tiempo. Por ejemplo, supongamos que está en Vancouver, si está editando una fecha en julio o en diciembre, puede significar que está editando una fecha en PST o PDT.

Le recomiendo que compruebe el fragmento de código a continuación para probar esta solución.

Conversiones de milisegundos

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

Conversiones de fechas

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

Véalo usted mismo

Darlesson
fuente
Esta es la respuesta real. Funcionó como un encanto para mí. Establecer una nueva Fecha (0) y agregar milisegundos es lo mismo que una nueva Fecha (milisegundos)
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());

EDITAR fijo

Amjad Masad
fuente
Pasé por esto en mi segundo ejemplo. Las diferencias que me da son entre 50 y 900, que es en milisegundos (que muestra el tiempo durante el procesamiento del cálculo, no la diferencia real)
Shane Reustle
Ninguno de ellos me ayuda. Les falta un método setUTCTime, que sería perfecto: P w3schools.com/jsref/jsref_obj_date.asp
Shane Reustle
No funciona, al menos en Firefox para Ubuntu. El código no debe establecer día / mes / año después de establecer la fecha.
Simon Kozlov
@Simon Kozlov En realidad, esa es una suposición incorrecta en el objeto de fecha, setDate y getDate se refieren al día del mes, y el problema es que utilicé funciones como (setUTCDay) que no existen, ¡sorprendido de que se haya aceptado!
Amjad Masad
@AmjadMasad Su respuesta sería más útil si también muestra el resultado esperado.
not2qubit
0

Teniendo en cuenta, tienes epoch_timedisponible,

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

@Amjad, buena idea, pero una mejor implementación sería:

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

Primero conviértalo a String y luego reemplace el texto de la zona horaria.

function convertUnixTime(time) {
  return new Date(time*1000).toString().replace("GMT+0530 (Sri Lanka Standard Time)","");
}
Niño robot
fuente