2016-01-05 11 views
6

Prima di Java8, ho utilizzato la classe DateTime di Joda per includere le informazioni sul fuso orario e posso facilmente convertire tra DateTime e sql Timestamp.Java 8 ZonedDateTime o OffsetDateTime per sostituire Joda DateTime

Una volta eseguita la migrazione a Java8, quale classe dovrei sostituire? OffsetDateTime o ZonedDateTime?

Inoltre, ho provato a utilizzare OffsetDateTime, ma sembra impossibile ricostruire a OffsetDateTime da un sql Timestamp.

Per Joda DateTime e Timestamp convertitore, il codice è come:

val joda = DateTime.now() 
val sqlJoda = new Timestamp(joda.getMillis) 
val jodaBack = new DateTime(sqlJoda) 

Ma per Java8,

val java8 = OffsetDateTime.now() 
val sqlJava8 = new Timestamp(java8.toInstant.toEpochMilli) 
val java8Back = ??? 

Qualcuno ha qualche idea in proposito? Sembra che Joda DateTime sia davvero buono.

risposta

3

È possibile utilizzare ZonedDateTime. Ecco alcuni esempi di codice che uso per convertire in Timestamp avanti e indietro.

public ZonedDateTime from(Timestamp timestamp) { 
    if (timestamp == null) { 
     return null; 
    } 
    final ZonedDateTime zonedDateTime = ZonedDateTime.ofInstant(timestamp.toInstant(), ZoneId.of("UTC")); 
    return zonedDateTime; 
} 

public Timestamp to(ZonedDateTime zonedDateTime) { 
    if (zonedDateTime == null) { 
     return null; 
    } 
    final Timestamp timestamp = Timestamp.valueOf(zonedDateTime.withZoneSameInstant(ZoneId.of("UTC")).toLocalDateTime()); 
    return timestamp; 
} 

prega di notare che devo conservare i tempi di data nel database in UTC.

+1

La mappatura ufficiale di un timestamp SQL è LocalDateTime (timestamp senza fuso orario) o OffsetDateTime (timestamp con fuso orario). Vedere ad esempio la Maintenance release 2 di JDBC 4 JCP qui: https://jcp.org/en/jsr/detail?id=221 – assylias

+0

Non lo sapevo. Grazie. C'è qualche documento là fuori? – spa

+0

Vedi anche: http://stackoverflow.com/a/31749317/829571 – assylias

6

Utilizzando l'API Java 8 in java.time si potrebbe effettuare le seguenti operazioni:

long ms_since_epoch = 1_500_000_000_000L; 
Instant instant = Instant.ofEpochMilli(ms_since_epoch); 

// convert milliseconds in UTC to date 
OffsetDateTime dateUTC = OffsetDateTime.ofInstant(instant, ZoneOffset.UTC); 

Utilizzando il convegno:

val java8 = OffsetDateTime.now() 
val sqlJava8 = new Timestamp(java8.toInstant.toEpochMilli) 
val java8Back = OffsetDateTime.ofInstant(sqlJava8.toInstant(), ZoneOffset.UTC); 
+0

Il che significa assumiamo il database è UTC, giusto? Grazie. – ttt

+2

Sì. Ma puoi cambiarlo con il tuo fuso orario corrispondente usando ZoneId differente. –

2

Suppongo che il tipo di database sia timestamp with time zone. Se si tratta di un timestamp without timezone, sarà necessario un diverso tipo/meccanismo di conversione.

Il JDBC 4.2 spec consiglia di associare un timestamp with time zone a OffsetDateTime. Ecco come puoi convertire tra un OffsetDateTime e un java.sql.Timestamp.

  • Da OffsetDateTime-Timestamp:

    Timestamp ts = ...; 
    OffsetDateTime odt = OffsetDateTime.ofInstant(ts.toInstant(), ZoneId.systemDefault()); 
    
  • Da Timestamp-OffsetDateTime:

    OffsetDateTime odt = ...; 
    Timestamp ts = Timestamp.from(odt.toInstant()); 
    
Problemi correlati