2011-09-20 11 views
83

Tengo una lista con valores largos (por ejemplo: 1220227200, 1220832000, 1221436800 ...) que descargué del servicio web. Debo convertirlo a Fechas. Desafortunadamente esta manera, por ejemplo:Convirtiendo Long to Date en Java devuelve 1970

Date d = new Date(1220227200); 

devuelve 1 Ene 1970. Alguien sabe otra manera de convertir correctamente?

+0

¿Podría decirnos qué valores espera usted? La cuestión de segundos/milisegundos puede ser válida, pero 1220227200 no es 1/1/1970.Parece que estás pasando 0 al constructor. Algún código más podría ayudar. – SJuan76

+1

@mmmiki - debe aceptar una respuesta – Stewart

+0

regresa el 15 de enero de 1970, aquí, no el 1 de enero. – njzk2

Respuesta

111

El Date constructor (haga clic en el enlace!) Acepta el tiempo que long en milisegundos, no segundos. Debe multiplicarlo por 1000 y asegúrese de proporcionarlo como long.

Date d = new Date(1220227200L * 1000); 

Esta muestra aquí

Dom Ago 31 de 20:00:00 GMT-04: 00 2008

+10

O, como alternativa, use 'Fecha d = nueva Fecha (TimeUnit.SECONDS.toMillis (1220227200L));' para obtener una solución más limpia y menos * magic-numberesque *. –

35

Parece que sus posiciones largas son segundos, y no milisegundos. Fecha constructor toma el tiempo en milisegundos, por lo

Date d = new Date(timeInSeconds * 1000); 
+4

¿por qué esto obtuvo un voto a favor? Aquí, disfruta de un voto en contra. – f1sh

+4

@ f1sh: No devolví el voto, pero la respuesta original fue diferente. Lo editó dentro de un período de gracia de 5 minutos. – BalusC

+0

gracias por la aclaración. Esa es la propia desventaja SO ...: -/ – f1sh

8

Aquellos son probablemente las marcas de tiempo en segundos y no en milisegundos que se requieren para la nueva fecha de java constructor (largo). Solo multiplícalos por 1000 y deberías estar bien.

+0

Bah ... 30 segundos demasiado lento: P –

+19

más correctamente 30000 milisegundos demasiado lento – SJuan76

0

Nueva fecha (número) devuelve una fecha que es number milisegundos después del 1 de enero de 1970. Es posible que el formato de fecha no muestre horas, minutos y segundos para que vea que es un poco después del 1 de enero de 1970.

Debe analizar la fecha de acuerdo con el enrutamiento de análisis correcto. No sé qué es un 1220227200, pero si es segundos después del 1 de ENERO de 1970, multiplíquelo para producir milisegundos. Si no es así, conviértalo de mil maneras a milisegundos después de 1970 (si desea continuar usando java.util.Date).

0

Trabaja para mí. Probablemente quiera multiplicarlo por 1000, ya que lo que obtiene son los segundos de 1970 y debe pasar los milisegundos desde enero de 1 1970

1

1220227200 corresponde al 15 de enero de 1980 (y de hecho nueva Fecha (1220227200) .toString () regresa "Thu Jan 15 03:57:07 CET 1970"). Si transfiere un valor largo a una fecha, es decir, antes del 01/01/1970, de hecho devolverá una fecha de 01/01/1970. Asegúrese de que sus valores no estén en esta situación (menor que 82800000).

3

Prueba esto:

Calendar cal = Calendar.getInstance(); 
cal.setTimeInMillis(1220227200 * 1000); 
System.out.println(cal.getTime()); 
3

Los valores largos, muy probablemente, corresponden a Epoch marcas de tiempo, y los valores son:

1220227200 = Mon, 01 Sep 2008 00:00:00 GMT

1220832000 = Mon, 08 de Sep 2008 00:00:00 GMT

1221436800 = Lun 15 Sep 2008 00:00:00 GMT

Uno puede convertir estos valores largos a java.util.Date, teniendo en cuenta el hecho java.util.Fecha utiliza millisecs - como dio a entender anteriormente, pero con algún defecto - como esto:

// note: enforcing long literals (L), without it the values would just be wrong. 
Date date = new Date(1220227200L * 1000L); 

Ahora, se mostrará la fecha correcta, se puede utilizar java.text.DateFormat como se ilustra más adelante:

DateFormat df = DateFormat.getDateTimeInstance(DateFormat.FULL, DateFormat.FULL); 
df.setTimeZone(TimeZone.getTimeZone("UTC")); 
System.out.println("Wrong date time value: " + date); 
System.out.println("Correct date time value: " + df.format(date)); 

a continuación se presentan los resultados de mostrar el valor convertido a largo java.util.Date sin uso y utilizando el Formato de Fecha:

Date wrong (off by 2 hours): Mon Sep 01 02:00:00 CEST 2008 
Correct date : Monday, 1 September 2008 00:00:00 o'clock UTC 
7

conjunto Sólo el tiempo en molinos de Calendario objetar

Calendar c = Calendar.getInstance(); 
c.setTimeInMillis(1385355600000l); 
System.out.println(c.get(Calendar.YEAR)); 
System.out.println(c.get(Calendar.MONTH)); 
System.out.println(c.get(Calendar.DAY_OF_MONTH)); 
// get Date 
System.out.println(c.getTime()); 
36

tl; dr

Instant.ofEpochSecond(1_220_227_200L) 

desconoce sus datos

La gente usa diferentes precisiones en el seguimiento de tiempo que un número desde una epoch. Así que cuando usted obtiene algunos números que se interpretarán como un recuento desde una época, debe determinar:

  • Qué época?
    Many epochs dates se han utilizado en varios sistemas. Comúnmente utilizado es POSIX/Unix time, donde la época es el primer momento de 1970 en UTC. Pero no debe asumir esta época.
  • ¿Qué precisión?
    ¿Estamos hablando de segundos, milliseconds, microseconds, o nanoseconds desde la época?
  • ¿Qué huso horario?
    Normalmente, un recuento desde la época está en UTC/GMT zona horaria, es decir, no tiene ningún desfase de zona horaria. Pero a veces, cuando se trata de programadores ignorantes inexpertos o de fecha, puede haber una zona horaria implícita.

En su caso, como han señalado otros, parece que le han dado segundos desde la época de Unix. Pero está pasando esos segundos a un constructor que espera milisegundos. Entonces la solución es multiplicar por 1,000.

Lecciones aprendidas:

  • Determine, no asuma, el significado de los datos recibidos.
  • Lee the doc.

Graph showing various granularities of resolution in date-time systems including whole seconds, milliseconds, microseconds, and nanoseconds.

sus datos

Sus datos parece estar en segundos enteros. Si suponemos una época de principios de 1970, y si suponemos zona horaria UTC, a continuación, 1,220,227,200 es el primer momento del primer día de septiembre de 2008.

Joda-Time

El java.util.Date y. Las clases de calendario incluidas con Java son notoriamente problemáticas. Evítales.Utilice en su lugar la biblioteca Joda-Time o la nueva java.time package incluida en Java 8 (e inspirada en Joda-Time).

Tenga en cuenta que a diferencia de j.u.Date, un DateTime en Joda-Time sabe realmente su propio time zone asignado. Por lo tanto, en el ejemplo del código Joda-Time 2.4 que se ve a continuación, tenga en cuenta que primero se analizan los milisegundos utilizando la suposición predeterminada de UTC. Luego, en segundo lugar, asignamos un huso horario de París para ajustar. Mismo momento en la línea de tiempo del universo, pero diferente wall-clock time. Para la demostración, nos ajustamos de nuevo, a UTC. Casi siempre es mejor especificar explícitamente su zona horaria deseada/esperada en lugar de confiar en un valor predeterminado implícito (a menudo la causa del problema en el trabajo de fecha y hora).

Necesitamos milisegundos para construir un DateTime. Así que tome su entrada de segundos y multiplique por mil. Tenga en cuenta que el resultado debe ser un long de 64 bits, ya que desbordaríamos un int de 32 bits.

long input = 1_220_227_200L; // Note the "L" appended to long integer literals. 
long milliseconds = (input * 1_000L); // Use a "long", not the usual "int". Note the appended "L". 

Feed que cuenta de milisegundos para el constructor. Ese constructor en particular asume que el recuento es de la época de Unix de 1970. Así que ajuste la zona horaria según lo deseado, después de la construcción.

Use proper time zone names, una combinación de continente y ciudad/región. Nunca use códigos de 3 o 4 letras, como EST, ya que no están estandarizados ni son únicos.

DateTime dateTimeParis = new DateTime(milliseconds).withZone(DateTimeZone.forID("Europe/Paris")); 

Para la demostración, ajuste la zona horaria nuevamente.

DateTime dateTimeUtc = dateTimeParis.withZone(DateTimeZone.UTC); 
DateTime dateTimeMontréal = dateTimeParis.withZone(DateTimeZone.forID("America/Montreal")); 

Volcar a la consola. Tenga en cuenta cómo la fecha es diferente en Montreal, ya que el nuevo día ha comenzado en Europa, pero todavía no en América.

System.out.println("dateTimeParis: " + dateTimeParis); 
System.out.println("dateTimeUTC: " + dateTimeUtc); 
System.out.println("dateTimeMontréal: " + dateTimeMontréal); 

Cuando se ejecuta.

dateTimeParis: 2008-09-01T02:00:00.000+02:00 
dateTimeUTC: 2008-09-01T00:00:00.000Z 
dateTimeMontréal: 2008-08-31T20:00:00.000-04:00 

java.time

Los fabricantes de Joda-Time nos han pedido que emigran a su sustitución, el marco java.time tan pronto como sea conveniente. Si bien Joda-Time continúa recibiendo apoyo activo, todo el desarrollo futuro se realizará en las clases java.time y sus extensiones en el proyecto ThreeTen-Extra.

El marco de java-time está definido por JSR 310 y está integrado en Java 8 y posterior. Las clases de java.time se han retrotraído a Java 6 & 7 en el proyecto ThreeTen-Backport y a Android en el proyecto ThreeTenABP.

Un Instant es un momento en la línea de tiempo en UTC con una resolución de nanosegundos. Su época es el primer momento de 1970 en UTC.

Instant instant = Instant.ofEpochSecond(1_220_227_200L); 

Aplicar una offset-from-UTCZoneOffset para obtener una OffsetDateTime.

Mejor aún, si se conoce, aplique una zona horaria ZoneId para obtener un ZonedDateTime.

ZoneId zoneId = ZoneId.of("America/Montreal"); 
ZonedDateTime zdt = ZonedDateTime.ofInstant(instant , zoneId); 
+1

Saludos amigo. Gran explicación Obtenía un nuevo DateTime () desde 1970, cuando me di cuenta de que lo estaba dando en segundos y lo requería en milisegundos. –