亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

為什么 Date 對象不代表 JVM 時區中的日期?

為什么 Date 對象不代表 JVM 時區中的日期?

白衣染霜花 2023-05-24 15:58:17
我有 UTC 日期,我需要創建與 UTC 具有完全相同值的 Date 對象(遺留原因)。我設法做到了:String date = "2012-05-05 12:13:14";TemporalAccessor formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")        .withZone(ZoneId.of("UTC"))        .parse(date);Instant instant = Instant.from(        formatter); //ZonedDateTime zdf = ZonedDateTime.ofInstant(instant,ZoneId.of("UTC"));Calendar calendar = Calendar.getInstance();calendar.set(zdf.getYear(),zdf.getMonthValue(),zdf.getDayOfMonth(),zdf.getHour(),zdf.getMinute(),zdf.getSecond());Date dt = calendar.getTime();Date d2 = Date.from(instant);然而,困擾我的是——當我創建日期對象時,它應該以我的 JVM 默認時區顯示日期。但是這里的dt值與我輸入的 UTC 日期完全相同,但dt2在我的默認時區中表示的日期相同,為什么會這樣?為什么一個沒有皈依而另一個被皈依了?感謝您的解釋!
查看完整描述

2 回答

?
慕標琳琳

TA貢獻1830條經驗 獲得超9個贊

保留時間與保留時刻

我會一一解釋中心線。

    Calendar calendar = Calendar.getInstance();

這將創建一個Calendar與 JVM 默認時區相同的時區。不像DateaCalendar 一個時區。

    calendar.set(zdf.getYear(),zdf.getMonthValue(),zdf.getDayOfMonth(),
            zdf.getHour(),zdf.getMinute(),zdf.getSecond());

這會將您設置Calendar為與您相同的掛鐘時間ZonedDateTime,即 12:13:14。由于 和ZonedDateTime具有Calendar不同的時區(分別為 UTC 和您當地的時區),這會導致不同的時刻。

@VGR 也是正確的:雖然日期是ZonedDateTIme5 月(第 5 個月),但您將月份設置Calendar為 6 月,因為Calendar令人困惑的月份是從 0 開始的,從 1 月的 0 到 12 月的 11。

    Date d2 = Date.from(instant);

Instant這是從到的正確轉換,Date并為您提供相同的時間點,與Instant. 因此與和不在同一個時刻。Calendardt

在您的問題中可能已經理解了,但是對于閱讀的任何人,我想直接聲明:Date并且Calendar設計不佳且早已過時。您不應使用它們,除非需要與您現在無法更改或不想升級的遺留 API 進行交互。對于所有其他用途,請堅持使用現代 Java 日期和時間 API java.time。


查看完整回答
反對 回復 2023-05-24
?
繁花不似錦

TA貢獻1851條經驗 獲得超4個贊

博士

  • 正如其他人所說,ajava.util.Date代表 UTC 中的一個時刻。它的toString方法是通過在生成格式不正確的字符串時動態應用 JVM 當前的默認時區來欺騙您。從不使用此類的眾多原因之一。

  • 不要浪費你的時間去理解那些可怕的類Date&?Calendar。它們現在是legacy,要避免。

  • 僅對所有日期時間處理使用java.time類。

細節

您將糟糕的遺留日期時間類 (?Date,?Calendar) 與其現代替代品 (?Instant,?ZonedDateTime) 混合在一起。不要混合這些。隨著JSR 310的采用,遺留類完全被java.time類取代。

無需使用DateCalendar再次使用。不要浪費時間去理解它們。它們被替換是有原因的——實際上有很多原因。動用您的智慧和時間來完成更有成效的工作。

如果您必須使用遺留類與尚未更新到java.time 的舊代碼進行互操作,請通過調用添加到舊類的新to…/轉換方法來來回轉換。使用java.timefrom…類執行業務邏輯、數據交換和數據存儲。

該類java.util.Date被替換為Instant.

java.util.Date?d?=?Date.from(?instant?)?;?????//?From??modern?to?legacy.
Instant?instant?=?d.toInstant()?;?????????????//?From?legacy?to?modern.

該類Calendar,或者更確切地說是其常用的子類GregorianCalendar,被替換為ZonedDateTime。假設你的Calendar對象真的是一個GregorianCalendar底層,你可以投射,然后轉換。

Calendar?c?=?GregorianCalendar.from(?zonedDateTime?)?;????????????????????????//?From??modern?to?legacy.
ZonedDateTime?zonedDateTime?=?(?(GregorianCalendar)?c?).toZonedDateTime()?;???//?From?legacy?to?modern.

這是一張將遺留類映射到現代類的圖表。

http://img2.sycdn.imooc.com/646dc3c80001d73106530375.jpg

查看完整回答
反對 回復 2023-05-24
  • 2 回答
  • 0 關注
  • 155 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號