2016-01-05 31 views
6

Przed Java8 użyłem klasy DateTime Jody do włączenia informacji o strefie czasowej i mogę z łatwością przekonwertować między DateTime i sql Timestamp.Java 8 ZonedDateTime lub OffsetDateTime zastąpienie Joda DateTime

Po migracji do Java8, którą klasę należy wymienić? OffsetDateTime lub ZonedDateTime?

Próbowałem również użyć OffsetDateTime, ale wydaje się, że nie można skonstruować z powrotem do OffsetDateTime z sql Timestamp.

Dla Joda DateTime i Timestamp konwertera, kod jest podobny:

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

Ale Java8,

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

Ktoś ma jakiś pomysł na ten temat? Wygląda na to, że Joda DateTime jest naprawdę dobra.

Odpowiedz

3

Można użyć ZonedDateTime. Oto przykładowy kod, którego używam do konwersji na Timestamp w tę iz powrotem.

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

Należy pamiętać, że przechowuję daty w bazie danych w UTC.

+1

Oficjalne odwzorowanie znacznika czasu SQL to: LocalDateTime (znacznik czasu bez strefy czasowej) lub OffsetDateTime (znacznik czasu ze strefą czasową). Patrz na przykład wersja 2 wydania JDBC 4 JCP tutaj: https://jcp.org/en/jsr/detail?id=221 – assylias

+0

Nie wiedziałem tego. Dzięki. Czy jest tam jakiś dokument? – spa

+0

Zobacz też: http://stackoverflow.com/a/31749317/829571 – assylias

6

Korzystanie z API Javy 8 w java.time można wykonać następujące czynności:

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

Korzystanie z konwencji:

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

Czyli zakładamy, że baza danych jest w UTC, prawda? Dzięki. – ttt

+2

Tak. Możesz go jednak zmienić na odpowiednią strefę czasową, używając innego identyfikatora ZoneId. –

2

Zakładam, że Twój typ bazy danych to timestamp with time zone. Jeśli jest to timestamp without timezone, będziesz potrzebować innego mechanizmu konwersji/typu.

Zaleca się, aby JDBC 4.2 spec zamapować timestamp with time zone na OffsetDateTime. Oto, jak można przekonwertować między OffsetDateTime i java.sql.Timestamp.

  • Od OffsetDateTime do Timestamp:

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

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