2017-05-07 260 views
0

如何將ZonedDateTime轉換爲SQL Timestamp並保留時區信息? 我試圖採取UTC劃的時間,將其轉換爲Timestamp,然後將其轉換回來,但是當我轉換爲Timestamp,它失去的時區信息和Timestamp在使用我的本地時區創建:如何保存UTC時間戳?

public static void main(String[] args) { 

    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("hh:mm a"); 

    ZonedDateTime zdtUTC = ZonedDateTime.now(ZoneId.of("UTC")); 

    ZonedDateTime zdtNY = zdtUTC.withZoneSameInstant(ZoneId.of("America/New_York")); 
    ZonedDateTime zdtAZ = zdtUTC.withZoneSameInstant(ZoneId.of("America/Phoenix")); 
    ZonedDateTime zdtUK = zdtUTC.withZoneSameInstant(ZoneId.of("Europe/London")); 

    System.out.println(formatter.format(zdtUTC) + " in UTC zone"); 
    System.out.println(formatter.format(zdtNY) + " in New York, NY"); 
    System.out.println(formatter.format(zdtAZ) + " in Phoenix, AZ"); 
    System.out.println(formatter.format(zdtUK) + " in London, UK"); 

    Timestamp timestamp = Timestamp.from(zdtUTC.toInstant()); 

    LocalDateTime converted = timestamp.toLocalDateTime(); 
    ZonedDateTime convertedZdt = ZonedDateTime.of(converted, ZoneId.of("UTC")); 

    System.out.println(timestamp); 

    System.out.println(formatter.format(convertedZdt) + " in UTC zone"); 

} 

06:33 PM in UTC zone 
02:33 PM in New York, NY 
11:33 AM in Phoenix, AZ 
07:33 PM in London, UK 
2017-05-07 14:33:06.745 
02:33 PM in UTC zone 

我需要做些什麼來確保Timestamp記錄使用正確的時區信息?

+0

您可以使用'&server Timezone = UTC&使用傳統日期時間代碼= false'成功 –

+1

SQL時間戳不*具有*時區 - 這只是時間上的即時。如果您需要單獨的時區,我建議將時區ID存儲在單獨的列中。如果您只關心該時間點的偏移量,則可以存儲該偏移量 - 但您需要知道,這與存儲時區不同。 –

+0

我的理解與存儲時區不同,但我需要能夠將時區絕對時間存儲在UTC時區的瞬間。我不允許修改數據庫表。所以如果我在紐約紐約時間下午3點,它需要存儲爲11AM,同樣如果我在倫敦,並且是4PM,它需要存儲爲3PM。否則,我從數據庫中檢索'Timestamp'時沒有參考點。 – DayTripperID

回答

2

當我轉換爲時間戳,它失去的時區信息,並使用我的本地時區

號當您轉換原有ZonedDateTime zdtUTCjava.sql.Timestamp你在同一時刻被創建的時間戳及時。這可以通過格式化並直接顯示timestamp值進行驗證:

Timestamp timestamp = Timestamp.from(zdtUTC.toInstant()); // as before 
// verify the timestamp value directly 
java.text.SimpleDateFormat sdfUTC = new java.text.SimpleDateFormat("hh:mm a z"); 
sdfUTC.setCalendar(java.util.Calendar.getInstance(java.util.TimeZone.getTimeZone("UTC"))); 
System.out.printf("timestamp is %s%n", sdfUTC.format(timestamp)); 

,將打印相同的值作爲輸出的第一行:

08:30 PM in UTC zone 
... 
timestamp is 08:30 PM UTC 

這是隨後轉化爲LocalDateTime,然後再到「丟失」時區信息的ZonedDateTime