2016-01-05 21 views
6

Trước Java8, tôi đã sử dụng lớp DateTime của Joda để bao gồm thông tin múi giờ và tôi có thể dễ dàng chuyển đổi giữa DateTime và sql Timestamp.Java 8 ZonedDateTime hoặc OffsetDateTime để thay thế Joda DateTime

Khi di chuyển sang Java8, lớp nào tôi nên thay thế? OffsetDateTime hoặc ZonedDateTime?

Ngoài ra, tôi đã cố gắng sử dụng OffsetDateTime, nhưng có vẻ như không thể xây dựng lại thành OffsetDateTime từ sql Timestamp.

Đối Joda DateTimeTimestamp chuyển đổi, mã này là như sau:

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

Nhưng đối với Java8,

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

Bất cứ ai cũng có một số ý tưởng về điều đó? Có vẻ như Joda DateTime thực sự tốt.

Trả lời

3

Bạn có thể sử dụng ZonedDateTime. Dưới đây là một số mã mẫu tôi sử dụng để chuyển đổi thành Timestamp qua lại.

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

Xin lưu ý rằng tôi lưu trữ ngày giờ trong cơ sở dữ liệu ở UTC.

+1

Ánh xạ chính thức của dấu thời gian SQL là LocalDateTime (dấu thời gian không có múi giờ) hoặc OffsetDateTime (dấu thời gian có múi giờ). Xem ví dụ bản phát hành Bảo trì 2 của JDBC 4 JCP tại đây: https://jcp.org/en/jsr/detail?id=221 – assylias

+0

Không biết điều đó. Cảm ơn. Có tài liệu nào không? – spa

+0

Xem thêm: http://stackoverflow.com/a/31749317/829571 – assylias

6

Sử dụng Java API 8 trong java.time bạn có thể làm như sau:

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

Sử dụng ước của bạn:

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

Có nghĩa là chúng ta giả định cơ sở dữ liệu là UTC, phải không? Cảm ơn. – ttt

+2

Có. Nhưng bạn có thể thay đổi nó thành múi giờ tương ứng của bạn bằng cách sử dụng ZoneId khác nhau. –

2

Tôi giả định rằng loại cơ sở dữ liệu của bạn là timestamp with time zone. Nếu đó là timestamp without timezone, bạn sẽ cần một cơ chế loại/chuyển đổi khác.

Các JDBC 4.2 spec đề xuất để lập bản đồ số timestamp with time zone thành OffsetDateTime. Dưới đây là cách bạn có thể chuyển đổi giữa một số OffsetDateTimejava.sql.Timestamp.

  • Từ OffsetDateTime-Timestamp:

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

    OffsetDateTime odt = ...; 
    Timestamp ts = Timestamp.from(odt.toInstant()); 
    
Các vấn đề liên quan