問題描述
Calendar c = Calendar.getInstance();
System.out.println(c.getTime());
c.set(2007, 0, 1);
System.out.println(c.getTime());
輸出:
2017 年 9 月 12 日星期二 12:36:24 IST
Tue Sep 12 12:36:24 IST 2017
2007 年 1 月 1 日星期一 12:36:24 IST
Mon Jan 01 12:36:24 IST 2007
但是,當我在不同的環境中使用相同的代碼時,輸??出變為以下:
But, When I use the same code in a different environment, Output changes to below:
輸出:
2017 年 9 月 12 日星期二 12:36:24 IST
Tue Sep 12 12:36:24 IST 2017
格林威治標準時間 2007 年 1 月 1 日星期一 12:36:24
Mon Jan 01 12:36:24 GMT 2007
僅供參考,我嘗試在設置值之前和之后打印日歷實例的時區,并且兩者都在IST"中.
FYI, I tried to print the timezone of the calendar instance, before and after setting the values and both are in "IST".
我想知道造成這種情況的根本原因.
I want to know the root cause of this.
推薦答案
您問題中的第二個輸出是運行愛爾蘭時間(歐洲/都柏林)的 JVM 上的正確和預期行為.2017 年 9 月 12 日,愛爾蘭處于夏令時 (DST).雖然沒有明確記錄,但 Date.toString()
(您在打印從 c.getTime()
獲得的 Date
時隱式調用) 打印 JVM 時區中的日期和時間,該時區在 9 月呈現為愛爾蘭夏令時的 IST.
The second output in your question is the correct and expected behaviour on a JVM running Irish time (Europe/Dublin). On September 12, 2017 Ireland is on summer time (DST). While it is not clearly documented, Date.toString()
(which you invoke implicitly when printing the Date
you get from c.getTime()
) prints the date and time in the JVM’s time zone, which in September is rendered as IST for Irish Summer Time.
當您在 Calendar
對象上同時使用愛爾蘭時間設置日期時,會保留一天中的小時;在您的情況下,您將獲得 2007 年 1 月 1 日 12:36:24 愛爾蘭標準時間.現在想象一下,如果愛爾蘭夏令時間和愛爾蘭標準時間都被呈現為 IST,會造成什么混亂.你將無法區分.相反,由于愛爾蘭標準時間與格林威治標準時間重合,當日期在一年中的夏季時間部分(即 1 月是't).
When you set the date on the Calendar
object also using Irish time, the hour of day is preserved; in your case you get Jan 01 2007 12:36:24 Irish standard time. Now imagine the confusion if both Irish Summer Time and Irish Standard Time were rendered as IST. You would not be able to distinguish. Instead, since Irish standard time coincides with GMT, this is what Date.toString()
prints when the date is not in the summer time part of the year (which January isn’t).
我的猜測是您的第一個輸出來自運行印度時間的 JVM.它也被呈現為 IST,并且由于印度不使用夏令時,因此夏季和冬季使用相同的縮寫.
My guess is that your first output is from a JVM running India time. It too is rendered as IST, and since India doesn’t use summer time, the same abbreviation is given summer and winter.
在理解您觀察到的行為的解釋之前,我發布了關于過時和現代 Java 日期和時間類的評論.不過,我仍然不認為評論是錯誤的.這是您的代碼的現代等價物:
Before understanding the explanation for the behaviour you observed, I posted a comment about the outdated and the modern Java date and time classes. I still don’t think the comment is way off, though. This is the modern equivalent of your code:
ZonedDateTime zdt = ZonedDateTime.now(ZoneId.of("Europe/Dublin"));
System.out.println(zdt);
zdt = zdt.with(LocalDate.of(2007, Month.JANUARY, 1));
System.out.println(zdt);
打印出來
2017-09-12T11:45:33.921+01:00[Europe/Dublin]
2007-01-01T11:45:33.921Z[Europe/Dublin]
如果要使用 JVM 的時區設置,請使用 ZoneId.systemDefault()
而不是 ZoneId.of("Europe/Dublin")
.正如名稱所述,與 Date
不同,ZonedDateTime
確實包含時區.它更多地對應于舊的 Calendar
類.如您所見,它的 toString
方法打印與 UTC 的偏移量(Z
表示零偏移量)和明確的 region/city 格式.我相信這會減少混亂的空間.如果要以特定格式打印日期,請使用 DateTimeFormatter
.
If you want to use the JVM’s time zone setting, use ZoneId.systemDefault()
instead of ZoneId.of("Europe/Dublin")
. As the name states, contrary to Date
, ZonedDateTime
does include a time zone. It corresponds more to the old Calendar
class. As you can see, its toString
method prints the offset from UTC (Z
meaning zero offset) and the time zone name in the unambiguous region/city format. I believe that this leaves a lot less room for confusion. If you want to print the date in a specific format, use a DateTimeFormatter
.
為了完整起見,以下是您的代碼在運行可能呈現為 IST 的不同時區時的輸出:
For the sake of completeness, here are the outputs from your code when running different time zones that may be rendered as IST:
歐洲/都柏林(同意您的第二個輸出)
Europe/Dublin (agrees with your second output)
Tue Sep 12 11:19:28 IST 2017
Mon Jan 01 11:19:28 GMT 2007
亞洲/特拉維夫
Asia/Tel_Aviv
Tue Sep 12 13:19:28 IDT 2017
Mon Jan 01 13:19:28 IST 2007
Asia/Kolkata(同意你的第一個輸出)
Asia/Kolkata (agrees with your first output)
Tue Sep 12 15:49:28 IST 2017
Mon Jan 01 15:49:28 IST 2007
這篇關于Calendar.getInstance().getTime() 在“GMT"中返回日期而不是默認時區的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!