![](/img/trans.png)
[英]How to handle daylight saving time properly in Java 7 without Joda Time?
[英]How to handle daylight saving time in Java using ObjectOutputStream and ObjectInputStream?
我正在傳遞一個哈希圖,其中包含日期為
2019-03-08 00:00:00.0
到servlet並在servlet端讀取hashmap時,我正在獲取日期
2019-03-07 23:00:00.0
它只能在夏令時轉換一小時。如何在Java中處理呢?
java.util.Date d = new java.util.Date();
d.setDate(06);
d.setMonth(02);
d.setYear(2018);
d.setHours(23);
d.setMinutes(59);
d.setSeconds(00);
ObjectInputStream is = new ObjectInputStream(request.getInputStream());
java.util.Date obj=(java.util.Date)is.readObject();
ObjectOutputStream objectOutputStream = new ObjectOutputStream(response.getOutputStream());
Vector vector = new Vector();
vector.add(d);
objectOutputStream.writeObject(vector);
objectOutputStream.flush();
objectOutputStream.close();
從Java類中讀取時,Iam減少了一個小時。
如果服務器時區設置未考慮夏令時(DST),可能會發生這種情況。 例如,我以美國/亞松森時區為例。 亞松森是巴拉圭最大的城市和首都。 巴拉圭在標准時間的偏移量為-04:00,但在夏季的偏移量為-03:00。 夏季時間仍在3月8日生效,直到3月24日。
首先說明出了什么問題:
System.setProperty("user.timezone", ZoneId.ofOffset("GMT", ZoneOffset.ofHours(-4)).getId());
// Send a timestamp from America/Asuncion time zone
ZoneId zone = ZoneId.of("America/Asuncion");
// Create the timestamp as March 8 at 00:00:00
Instant testTime
= ZonedDateTime.of(2019, 3, 8, 0, 0, 0, 0, zone).toInstant();
Timestamp ts = Timestamp.from(testTime);
try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
try (ObjectOutputStream objectOutputStream = new ObjectOutputStream(baos)) {
objectOutputStream.writeObject(ts);
}
byte[] ba = baos.toByteArray();
try (ObjectInputStream is = new ObjectInputStream(new ByteArrayInputStream(ba))) {
java.util.Date obj = (java.util.Date) is.readObject();
System.out.println(obj);
}
}
對於這個簡單的演示,我們不需要單獨的客戶端和服務器代碼。 我創建一個在相關時區中具有已知日期和時間的Timestamp
對象,將其寫入ObjectOutputStream
並使用相同的基礎字節從ObjectInputStream
讀取回。 我得到的是代表同一時間點的Timestamp
。 為了演示接收器打印時會發生什么,我將默認時區設置在頂部。 我正在使用-04:00
的恆定偏移量來演示服務器時區未考慮夏令時時會發生什么。 它打印:
2019-03-07 23:00:00.0
因此,您得到的結果相同。 這是因為-令人困惑Timestamp.toString
使用JVM的時區設置來生成字符串。
怎么修?
當我們知道Timestamp
是從America / Asuncion時區發送的時,我們可以在服務器上顯式使用該時區:
java.util.Date obj = (java.util.Date) is.readObject();
ZonedDateTime timeAsSent = obj.toInstant().atZone(zone);
System.out.println(timeAsSent);
2019-03-08T00:00-03:00 [美國/亞松森]
現在時間與最初寫入對象輸出流的時間一致。
更好的修復
如果可以的話,請完全避免使用舊的類Date
和Timestamp
。 這些課程的設計不佳,會在您身上耍花樣。 他們也早已過時。 而是將ZonedDateTime
或Instant
寫入客戶端的對象流中,當然還要在服務器端讀取相同的類型。 這樣就不會有驚喜的余地。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.