英文:
Java Calendar isn't showing correct HOUR_OF_DAY
问题
我正在使用Java中的Calendar类,遇到了问题。我有这段代码
```java
Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("NZST"));
System.out.println("Calendar.HOUR_OF_DAY = " + calendar.get(Calendar.HOUR_OF_DAY));
System.out.println("Calendar.HOUR = " + calendar.get(Calendar.HOUR));
System.out.println("calendar.getTime() = " + calendar.getTime());
我期望它输出
Calendar.HOUR_OF_DAY = 17
Calendar.HOUR = 5
calendar.getTime() = Sat Aug 08 17:45:53 NZST 2020
但实际上它输出
Calendar.HOUR_OF_DAY = 5
Calendar.HOUR = 5
calendar.getTime() = Sat Aug 08 17:45:53 NZST 2020
所以为什么HOUR_OF_DAY和HOUR返回相同的值,而calendar.getTime()显示正确的HOUR_OF_DAY。它们都使用NZST时区。
<details>
<summary>英文:</summary>
I am using the Calendar class in java and am having trouble. I have this code
Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("NZST"));
System.out.println("Calendar.HOUR_OF_DAY = " + calendar.get(Calendar.HOUR_OF_DAY));
System.out.println("Calendar.HOUR = " + calendar.get(Calendar.HOUR));
System.out.println("calendar.getTime() = " + calendar.getTime());
and I would expect it to output
Calendar.HOUR_OF_DAY = 17
Calendar.HOUR = 5
calendar.getTime() = Sat Aug 08 17:45:53 NZST 2020
but instead it outputs
Calendar.HOUR_OF_DAY = 5
Calendar.HOUR = 5
calendar.getTime() = Sat Aug 08 17:45:53 NZST 2020
So why does the HOUR_OF_DAY and HOUR return the same thing however, calendar.getTime() shows the correct HOUR_OF_DAY. They are both using NZST.
</details>
# 答案1
**得分**: 3
他们都在使用NZST。
不,他们不是,尽管我能理解为什么你会这么认为。
第一个实际上是在使用UTC,因为“NZST”不是一个有效的时区标识符。很遗憾,`TimeZone.getTimeZone` 在你提供无效标识符时不会引发异常,但现在无法更改了 :(
`calendar.getTime()` 返回一个`Date`引用,而[`Date`没有时区](https://codeblog.jonskeet.uk/2017/04/23/all-about-java-util-date/),所以它会以你系统的本地时区打印出来,巧合的是这个时区是新西兰。
如果你将你的第一行代码更改为使用一个*真正的*时区标识符,它就会按你的预期行为:
```java
Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("Pacific/Auckland"));
在Java中,一些缩写(如NZST)被识别为时区标识符,但始终最好使用完整的IANA时区标识符,比如“Pacific/Auckland”。
英文:
> They are both using NZST.
No, they're not, although I can see why you think they are.
The first is actually using UTC, because "NZST" is not a valid time zone ID. It's a shame that TimeZone.getTimeZone
doesn't throw an exception when you present it with an invalid ID, but that can't be changed now
calendar.getTime()
is returning a Date
reference, and Date
doesn't have a time zone so it's printing in your system local time zone - which happens to be New Zealand.
If you change your first line of code to use a real time zone ID, it behaves as you expect it to:
Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("Pacific/Auckland"));
A few abbreviations (like NZST) are recognized as time zone IDs in Java, but it's always better to use the full IANA time zone ID, like "Pacific/Auckland".
答案2
得分: 1
tl;dr
ZonedDateTime
.now(
ZoneId.of( "太平洋/奥克兰" )
)
.getHour()
详细信息
Jon Skeet的答案是正确的。此外,您正在使用多年前由JSR 310中定义的java.time类所取代的可怕类。
java.time中的ZoneId
类替代了遗留类TimeZone
。这个ZoneId
类满足了Jon Skeet答案中的要求:如果您提供一个错误的区域ID,比如NZST
,它会抛出异常。
java.time
ZoneId z = ZoneId.of( "太平洋/奥克兰" ) ; // 指定一个时区。一个特定地区的人民使用的偏离UTC的过去、现在和未来的变化的历史。
ZonedDateTime zdt = ZonedDateTime.now( z ) ; // 捕捉当前时间在特定时区的视图。
int hour = zdt.getHour() ; // 提取一天中的小时。
英文:
tl;dr
ZonedDateTime
.now(
ZoneId.of( "Pacific/Auckland" )
)
.getHour()
Details
The Answer by Jon Skeet is correct. In addition, you are using terrible classes that were supplanted years ago by the java.time classes defined in JSR 310.
The ZoneId
class in java.time replaces the legacy class TimeZone
. This class ZoneId
fulfills the wish in Jon Skeet’s Answer: If you feed it a false zone ID like NZST
, it throws an exception.
java.time
ZoneId z = ZoneId.of( "Pacific/Auckland" ) ; // Specify a time zone. A history of past, present, and future changes to the offset-from-UTC used by the people of a particular region.
ZonedDateTime zdt = ZonedDateTime.now( z ) ; // Capture the current time as seen in a particular time zone.
int hour = zdt.getHour() ; // Extract the hour of he day.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论