2011-09-20 14 views
83

Ho una lista con valori lunghi (ad esempio: 1220227200, 1220832000, 1221436800 ...) che ho scaricato dal servizio web. Devo convertirlo in date. Purtroppo in questo modo, ad esempio:Conversione Long to Date in Java restituisce 1970

Date d = new Date(1220227200); 

rendimenti 1 gennaio 1970. Chiunque conosce un altro modo per convertire in modo corretto?

+0

Puoi dire quali valori ti aspetti? La domanda di secondi/millisecondi può essere valida, ma 1220227200 non è 1/1/1970.Sembra che tu stia passando 0 al costruttore. Qualche altro codice potrebbe aiutare. – SJuan76

+1

@mmmiki - dovresti accettare una risposta – Stewart

+0

restituisce il 15 gennaio 1970, qui, non il primo gennaio. – njzk2

risposta

111

Il Date constructor (clicca il link!) Accetta il tempo come long in millisecondi, non secondi. Devi moltiplicarlo per 1000 e assicurarti di fornirlo come long.

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

Questa mostra qui

Sole 31 agosto 20:00:00 GMT-04: 00 2008

+10

In alternativa, utilizzare 'Data d = new Date (TimeUnit.SECONDS.toMillis (1220227200L));' per una soluzione più pulita e meno * magic-numberesque *. –

35

Sembra che i tuoi anela sono secondi, e non millisecondi. Data costruttore richiede tempo in millisecondi, quindi

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

perché questo ha avuto un downvote? Qui, goditi un contro-voto. – f1sh

+4

@ f1sh: Non ho fatto downvot, ma la risposta originale era diversa. L'ha modificato in un periodo di grazia di 5 minuti. – BalusC

+0

grazie per il chiarimento. Questo è il vero inconveniente SO ha ...: -/ – f1sh

8

Quelli sono probabilmente timestamp in secondi e non in millisecondi che è richiesto per Java nuovo Data costruttore (lunga). Basta moltiplicarli per 1000 e dovresti essere a posto.

+0

Bah .. 30 secondi troppo lento: P –

+19

più propriamente 30000 millisecondi troppo lento – SJuan76

0

Nuova data (numero) restituisce una data che è number millisecondi dopo il 1 gennaio 1970. Le probabilità sono che il formato della data non mostra ore, minuti e secondi per poter vedere che è solo un po 'dopo il 1 gennaio 1970.

È necessario analizzare la data in base al corretto percorso di analisi. Non so cosa sia un 1220227200, ma se sono secondi dopo il 1 ° gennaio 1970, moltiplicarlo per produrre millisecondi. In caso contrario, convertirlo in qualche modo in millisecondi dopo il 1970 (se si desidera continuare a utilizzare java.util.Date).

0

Lavori per me. Probabilmente vuoi moltiplicarlo con 1000, dal momento che ciò che ottieni sono i secondi del 1970 e devi passare i millisecondi da gennaio 1 1970

1

1220227200 corrisponde al 15 gennaio 1980 (e infatti nuova Data (1220227200) .toString () restituisce "Gio 15 Gen 03:57:07 CET 1970"). Se si passa un valore lungo a una data, ovvero prima del 01/01/1970, verrà restituita una data 01/01/1970. Assicurati che i tuoi valori non siano in questa situazione (inferiore a 82800000).

3

Prova questo:

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

I valori lunghi, molto probabilmente, corrispondono a Epoch timestamp, ed i valori sono:

1220,2272 milioni = Mon, 1 settembre 2008 00:00:00 GMT

1.220.832 mila = Mon, 8 Settembre 2008 00:00:00 GMT

1221,4368 milioni = lun 15 set 2008 00:00:00 GMT

Uno può convertire questi valori lunghi in java.util.Date, tenendo conto del fatto java.util.Data utilizza millisecs - come già accennato, ma con qualche difetto - in questo modo:

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

Ora, per visualizzare la data in modo corretto, si può usare java.text.DateFormat come di seguito illustrato:

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

di seguito sono riportati i risultati di visualizzazione del valore lungo convertito java.util.Date senza utilizzare e utilizzando il DateFormat:

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

impostare solo il tempo di mulini sul calendario opporsi

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) 

conoscere i Suoi dati

Le persone usano diverse precisioni nel monitoraggio di tempo come un numero in quanto un epoch. Così, quando si ottiene alcuni numeri da interpretare come un conteggio in quanto un'epoca, è necessario determinare:

  • quale epoca?
    Many epochs dates sono stati utilizzati in vari sistemi. Comunemente utilizzato è POSIX/Unix time, dove l'epoca è il primo momento del 1970 in UTC. Ma non dovresti assumere questa epoca.
  • Che precisione?
    Stiamo parlando di secondi, milliseconds, microseconds o nanoseconds dall'epoca?
  • Che fuso orario?
    Generalmente un conteggio poiché l'epoca è nel fuso orario UTC/GMT, ovvero non ha alcun offset del fuso orario. Ma a volte, quando coinvolgono programmatori ignoranti inesperti o con data e ora, potrebbe esserci un fuso orario implicito.

Nel tuo caso, come altri hanno notato, sembra che ti siano stati dati dei secondi dall'epoca Unix. Ma stai passando quei secondi a un costruttore che si aspetta millisecondi. Quindi la soluzione è moltiplicare per 1.000.

Lezioni apprese:

  • Determinare, non date per scontato, il significato dei dati ricevuti.
  • Leggi the doc.

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

vostri dati

I dati sembra essere in secondi interi. Se assumiamo un'epoca dell'inizio del 1970, e se assumiamo UTC fuso orario, quindi 1,220,227,200 è il primo momento del primo giorno del mese di settembre 2008.

Joda Time

Il java.util.Date e le classi .Calendar in bundle con Java sono notoriamente fastidiose. Evitalo.Utilizzare invece la libreria Joda-Time o il nuovo java.time package in bundle in Java 8 (e ispirato a Joda-Time).

Si noti che a differenza di j.u.Date, uno DateTime in Joda-Time conosce veramente il proprio time zone assegnato. Quindi nell'esempio codice Joda-Time 2.4 visto di seguito, si noti che prima analizziamo i millisecondi usando l'assunto di default di UTC. Quindi, in secondo luogo, assegniamo un fuso orario di Parigi da regolare. Lo stesso momento nella linea temporale dell'universo, ma diverso wall-clock time. Per la dimostrazione, ci adeguiamo di nuovo, a UTC. Quasi sempre è meglio specificare esplicitamente il fuso orario desiderato/atteso piuttosto che fare affidamento su un default implicito (spesso causa di problemi nel lavoro di data-ora).

Abbiamo bisogno di millisecondi per costruire un DateTime. Prendi il tuo input di secondi e moltiplicalo per mille. Si noti che il risultato deve essere un long a 64 bit poiché si verificherà un overflow a 32 bit int.

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 quel conteggio di millisecondi al costruttore. Quel particolare costruttore presuppone che il conteggio sia dell'epoca Unix del 1970. Quindi regolare il fuso orario come desiderato, dopo la costruzione.

Utilizzare i nomi proper time zone, una combinazione di continente e città/regione. Non utilizzare mai codici a 3 o 4 lettere come EST poiché non sono né standardizzati né unici.

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

Per la dimostrazione, regolare di nuovo il fuso orario.

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

Discarica per consolle. Nota come la data è diversa a Montréal, poiché il nuovo giorno è iniziato in Europa, ma non ancora in America.

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

Quando eseguito.

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

I creatori di Joda-Time ci hanno chiesto di migrare verso la sua sostituzione, il quadro java.time non appena è conveniente. Mentre Joda-Time continua a essere attivamente supportato, tutto lo sviluppo futuro sarà fatto sulle classi java.time e sulle loro estensioni nel progetto ThreeTen-Extra.

Il framework java-time è definito da JSR 310 e incorporato in Java 8 e versioni successive. Le classi java.time sono state sottoposte a back-porting su Java 6 & 7 sul progetto ThreeTen-Backport e su Android nel progetto ThreeTenABP.

Un Instant è un momento sulla timeline in UTC con una risoluzione di nanosecondi. La sua epoca è il primo momento del 1970 in UTC.

Instant instant = Instant.ofEpochSecond(1_220_227_200L); 

Applicare un offset-from-UTCZoneOffset per ottenere un OffsetDateTime.

Meglio ancora, se noto, applicare un fuso orario ZoneId per ottenere un ZonedDateTime.

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

Cheers amico. Ottima spiegazione. Stavo ricevendo un nuovo DateTime () dal 1970 quando ho capito che lo stavo dando in pochi secondi e richiesto in millisecondi –