2012-12-06 19 views
21

Come si formatta uno javax.time.Instant come stringa nel fuso orario locale? Quanto segue traduce uno Instant locale a UTC, non al fuso orario locale come mi aspettavo. La rimozione della chiamata a toLocalDateTime() fa lo stesso. Come posso ottenere l'ora locale invece?Come si formatta un javax.time.Instant come una stringa nel fuso orario locale?

public String getDateTimeString(final Instant instant) 
{ 
    checkNotNull(instant); 
    DateTimeFormatterBuilder builder = new DateTimeFormatterBuilder(); 
    DateTimeFormatter formatter = builder.appendPattern("yyyyMMddHHmmss").toFormatter(); 
    return formatter.print(ZonedDateTime.ofInstant(instant, TimeZone.UTC).toLocalDateTime()); 
} 

Nota: Stiamo usando la versione precedente 0.6.3 dell'attuazione JSR-310 di riferimento.

risposta

0

Prima di votare giù la mia risposta, si prega di notare che la questione in modo esplicito (e in grassetto) si riferisce alla vecchia versione 0.6.3 dell'implementazione di riferimento JSR-310! Ho fatto questa domanda nel dicembre 2012, molto prima dell'arrivo di Java 8 e della nuova libreria di date!


ho rinunciato a JSR-310 classi DateTimeFormatter e ZonedDateTime e invece ricorso a vecchio stile java.util.Date e java.text.SimpleDateFormat:

public String getDateTimeString(final Instant instant) 
{ 
    checkNotNull(instant); 
    DateFormat format = new SimpleDateFormat("yyyyMMddHHmmss"); 
    Date date = new Date(instant.toEpochMillisLong()); 
    return format.format(date); 
} 
+0

Non vedo davvero la necessità di ricorrere a questo vecchio approccio. –

+0

@ SimonAndréForsberg: Sfortunatamente dovevo perché stavamo usando 0.6.3 dell'implementazione di riferimento JSR-310. Fortunatamente, sebbene il nostro prodotto utilizzi ancora Java 7, da allora siamo passati all'ultima JSR-310 che appare in Java 8. –

+0

Date ha anche un metodo per questo, Date.from (istantaneo). Nwm, guarda la tua strana versione ora – softarn

6

Perché dovresti utilizzare il fuso orario locale? Stai chiedendo esplicitamente UTC:

ZonedDateTime.ofInstant(instant, TimeZone.UTC) 

Basta specificare il fuso orario locale invece:

ZonedDateTime.ofInstant(instant, TimeZone.getDefault()) 
+0

Mi aspettavo 'toLocalDateTime()' per convertirlo nel fuso orario locale o predefinito. Apparentemente, ho frainteso cosa 'toLocatlDateTime()' fa. Pensavo di poter creare un 'LocalDateTime', ma questa classe non ha alcun metodo che converta un' Instant' in un 'LocalDateTime'. –

+2

@DerekMahar: Local non significa quello che pensi che faccia, in pratica. Significa solo una data e un'ora che non è associata a nessun particolare fuso orario.Ad esempio, in tutto il mondo, il nuovo anno inizia a mezzanotte del 1 ° gennaio. Per ogni anno particolare, si tratta di un LocalDateTime, che si verifica in istanti diversi * per diversi fusi orari. –

+0

Sfortunatamente, JSR-310 non usa 'java.util.TimeZone' e la classe' javax.time.calendar.TimeZone' nella versione 0.6.3 di JSR-310 non sembra avere il metodo 'getDefault()' o qualsiasi metodo simile –

34

Rispondere a questa domanda WRT la quasi finito JDK1.8 versione

DateTimeFormatter formatter = 
    DateTimeFormatter.ofPattern("yyyyMMddHHmmss").withZone(ZoneId.systemDefault()); 
return formatter.format(instant); 

La chiave è che Instant non ha alcun fuso orario ionico. Pertanto non può essere formattato utilizzando alcun pattens basato su campi data/ora, come "yyyyMMddHHmmss". Specificando la zona nel DateTimeFormatter, l'istante viene convertito nel fuso orario specificato durante la formattazione, consentendone il corretto output.

Un approccio alternativo è quello di convertire a ZonedDateTime:

DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMddHHmmss"); 
return formatter.format(ZonedDateTime.ofInstant(instant, ZoneId.systemDefault())); 

Entrambi gli approcci sono equivalenti, tuttavia vorrei generalmente scegliere la prima se il mio oggetto dati è stato un Instant.

+0

Grazie per la risposta. Ho pochi dubbi sul fatto che sia corretto, ma dovrò aspettare la prossima occasione per applicare questa soluzione al posto di quella che ho implementato. Dovrei anche aspettare che il nostro team sostituisca la versione 0.6.3 di JSR-310 con una versione più recente o sostituire JDK 6 con JDK 8. –

1

Prova questo:

String dateTime = DateTimeFormatter.ISO_ZONED_DATE_TIME.format(
    ZonedDateTime.ofInstant(instant, ZoneId.systemDefault()) 
); 

Questo dà:

2014-08-25T21:52:07-07:00[America/Los_Angeles] 

È possibile modificare il formato utilizzando qualcosa di diverso DateTimeFormatter.ISO_ZONED_DATE_TIME come il formattatore. DateTimeFormatter ha un sacco di formattatori predefiniti, oppure puoi definirne uno tuo.

+0

Non riesco a trovare la classe 'ZoneId' nella versione 0.6.3 del JSR -310 implementazione di riferimento. –