2015-06-04 11 views
7

Tôi có một java.time.OffsetDateTime mà tôi muốn chuyển đổi thành java.sql.Timestamp. Kể từ Timestamp không lưu trữ bất kỳ thông tin bù đắp, tôi sẽ lưu trữ tất cả các ngày/lần trong cơ sở dữ liệu như UTC.Chuyển đổi OffsetDateTime thành UTC Timestamp

Làm cách nào để chuyển đổi OffsetDateTime thành Timestamp bằng UTC?

EDIT:

Tôi tin rằng đây là câu trả lời nhưng có vẻ như là cách khá phức tạp để bí mật để UTC:

OffsetDateTime dateTime = OffsetDateTime.now(); 
Timestamp timestamp = Timestamp.valueOf(dateTime.atZoneSameInstant(ZoneId.of("Z")).toLocalDateTime()); 

Trả lời

7

Đây sẽ là cách để thực hiện chuyển đổi và đảm bảo UTC được sử dụng. Điều đó tôi nghĩ là một chút sạch hơn so với giải pháp được đề xuất bằng cách sử dụng các giây epoch.

Timestamp test = Timestamp.valueOf(entityValue.atZoneSameInstant(ZoneOffset.UTC).toLocalDateTime()); 
+0

Điều này là sai. Nếu 'dateTime' chứa' 2015-10-23T12: 44: 43Z' và bạn đang ở múi giờ UTC + 2 thì 'dấu thời gian' sẽ giữ' 2015-10-23 14: 44: 43.0' và khác với kết quả được cung cấp bởi giải pháp trong câu trả lời ('2015-10-23 12: 44: 43.0'). – rve

+0

Có, Dấu thời gian.Từ (tức thì) dường như chuyển đổi nó thành múi giờ địa phương của bạn. Một cách khác để làm điều này và đảm bảo nó vẫn còn trong UTC là 'Timestamp test = Timestamp.valueOf (entityValue.atZoneSameInstant (ZoneOffset.UTC) .toLocalDateTime());' Tôi đã chỉnh sửa câu trả lời ở trên phản ánh điều đó. – Notso

+1

Để làm rõ các ý kiến ​​ở trên để tham khảo trong tương lai: Trước đây câu trả lời của tôi đã gợi ý rằng Timestamp.from (entityValue.toInstant) sẽ làm điều đó. Tuy nhiên, trong khi tức thời là một bản chất ngay lập tức trên dòng thời gian từ thời đại, Timestamp.from (tức thì) trả về nó trong múi giờ địa phương của bạn như @rve lưu ý. Vì vậy, một cách để làm điều này và đảm bảo nó vẫn còn trong UTC là 'Timestamp test = Timestamp.valueOf (entityValue.atZoneSameInstant (ZoneOffset.UTC) .toLocalDateTime());' – Notso

2

Sử dụng .toEpochSecond() để có đượC# giây kể từ ngày tài liệu tham khảo (trong UTC), nhân với 1000 và chuyển giá trị này tới hàm tạo Timestamp (vì nó dự kiến ​​là mili giây).

new Timestamp(1000 * offsetDateTime.toEpochSecond()); 
+0

Điều này sẽ mất thông tin về nano giây mặc dù - phải không? – Cheetah

+0

Vâng, có thể câu trả lời của riêng bạn là tốt hơn. – Glorfindel

3

Một giải pháp khác sẽ là:

Timestamp.valueOf(LocalDateTime.ofInstant(dateTime.toInstant(), ZoneOffset.UTC)); 

Nó chuyển đổi các dateTime để UTC, dải thông tin múi giờ và sau đó chuyển kết quả đến một Timestamp. Nó vẫn còn phức tạp nhưng IMHO nó sạch hơn một chút.

Chỉ cần sử dụng toInstance() hoặc toEpochSeconds() sẽ điều chỉnh kết quả với bù trừ được cung cấp.

Sau đây cho thấy các kết quả kiểm tra từ này và câu trả lời khác:

OffsetDateTime dateTime = 
    OffsetDateTime.of(2015, 10, 23, 12, 44, 43, 0, ZoneOffset.UTC); 
    // OffsetDateTime.of(2015, 10, 23, 12, 44, 43, 0, ZoneOffset.ofHours(-5)); 

err.println("dateTime   = " 
    + dateTime 
); 

err.println("as LocalDateTime = " 
    + dateTime.toLocalDateTime() 
); 

err.println("as timestamp (mine) = " 
    + Timestamp.valueOf(LocalDateTime.ofInstant(dateTime.toInstant(), ZoneOffset.UTC)) 
); 

err.println("@Cheetah (correct) = " 
    + Timestamp.valueOf(dateTime.atZoneSameInstant(ZoneId.of("Z")) 
     .toLocalDateTime()) 
); 

err.println("@Notso (wrong)  = " 
    + Timestamp.from(dateTime.toInstant()) 
); 

err.println("@Glorfindel (wrong) = " 
    + new Timestamp(1000 * dateTime.toEpochSecond()) 
); 

mang đến cho các kết quả như sau (múi giờ của tôi là CET):

(with ZoneOffset.UTC) 
dateTime   = 2015-10-23T12:44:43Z 
as LocalDateTime = 2015-10-23T12:44:43 
as timestamp (mine) = 2015-10-23 12:44:43.0 
@Cheetah (correct) = 2015-10-23 12:44:43.0 
@Notso (wrong)  = 2015-10-23 14:44:43.0 
@Glorfindel (wrong) = 2015-10-23 14:44:43.0 

(with ZoneOffset.ofHours(-5)) 
dateTime   = 2015-10-23T12:44:43-05:00 
as LocalDateTime = 2015-10-23T12:44:43 
as timestamp (mine) = 2015-10-23 17:44:43.0 
@Cheetah (correct) = 2015-10-23 17:44:43.0 
@Notso (wrong)  = 2015-10-23 19:44:43.0 
@Glorfindel (wrong) = 2015-10-23 19:44:43.0 

(Phiên bản từ Notso trên là trước khi chỉnh sửa ngày 17 tháng 2 năm 2016)

Các vấn đề liên quan