Java 8 的新 Java 日期时间 API 是否会处理 DST?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/32833896/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Does Java 8's new Java Date Time API take care of DST?
提问by Raja
I am thinking of using the new java 8 Date Time API. I googled a bit and found jodaTime as good choice for java but still kind of interested to see how this new API works.
我正在考虑使用新的java 8 Date Time API。我用谷歌搜索了一下,发现 jodaTime 是 Java 的不错选择,但仍然有兴趣了解这个新 API 是如何工作的。
I am storing all time in UTC values in my datastore and will be converting them to Local Time Zone specific value based on user's timezone. I can find many articles showing how to use new Java Date Time API. However I am not sure if the API will take care of DST changes ? Or do we have any better way of handling Date ?
我将所有时间以 UTC 值存储在我的数据存储中,并将根据用户的时区将它们转换为本地时区特定值。我可以找到许多展示如何使用新的 Java 日期时间 API 的文章。但是我不确定 API 是否会处理 DST 更改?或者我们有更好的处理 Date 的方法吗?
I am just learning the new Date API , so thought of hearing your thoughts on handling the DateTime and displaying it on the basis of Users TimeZone.
我只是在学习新的 Date API ,所以想听听您对处理 DateTime 并根据用户时区显示它的想法。
回答by Andreas
It depends on which class you use:
这取决于您使用哪个类:
Instant
is an instantaneous point on the global time-line (UTC), and is unrelated to time-zone.LocalDate
andLocalDateTime
have no concept of time-zone, but callingnow()
will of course give you your correct time.OffsetDateTime
has a time-zone, but doesn't support Daylight Savings Time.ZonedDateTime
has full time-zone support.
Instant
是全球时间轴 (UTC) 上的一个瞬时点,与时区无关。LocalDate
并且LocalDateTime
没有时区的概念,但是打电话now()
当然会给你正确的时间。OffsetDateTime
有时区,但不支持夏令时。ZonedDateTime
有完整的时区支持。
Converting between them usually requires a time-zone, so to answer your question:
它们之间的转换通常需要一个时区,所以要回答你的问题:
Yes, Java 8 Date/Time cantake care of DST, ifyou use it right.
是的,如果您使用得当,Java 8 日期/时间可以处理 DST 。
回答by Basil Bourque
The Answerby Andreasis spot-on correct.
Example Code
示例代码
Let's test it with some code. DST in the United States& Canada expires this year at 02:00 on November 1, 2015.
让我们用一些代码来测试一下。美国和加拿大的夏令时将于今年 2015 年 11 月 1 日 02:00 到期。
Let‘s start with 1 AM in “local” date-time, meaning not tied to the timeline and ignoring the issue of time zones. Add an hour, and we get 2 AM. Makes sense.
让我们从“本地”日期时间的凌晨 1 点开始,这意味着不受时间线限制并忽略时区问题。再增加一个小时,我们就到了凌晨 2 点。说得通。
LocalDateTime localDateTime = LocalDateTime.of( 2015 , Month.NOVEMBER , 1 , 1 , 0 ); // 1 AM anywhere. Not tied the timeline nor to any time zone.
LocalDateTime localDateTimeOneHourLater = localDateTime.plusHours( 1 ); // 2 AM anywhere, in no particular time zone, ignoring DST.
Next we get specific, with a particular time zone. We take that 1 AM anywhere and put it into the time zone of America/Los_Angeles
(west coast of United States).
接下来我们得到具体的,具有特定的时区。我们把那个凌晨 1 点放在任何地方,并将其放入America/Los_Angeles
(美国西海岸)的时区。
ZoneId zoneId_LosAngeles = ZoneId.of( "America/Los_Angeles" );
ZonedDateTime before = localDateTime.atZone( zoneId_LosAngeles ); // Assign a time zone, tying this vague date-time idea/generality to an actual moment on the time line.
Now add an hour, and see what we get. If DST is ignored, we'll get 2 AM. If DST is respected, we'll get 1 AM… when reaching 2 AM the wall-clock timejumps back to 1 AM but with a new offset-from-UTC. This is colloquially known as "fall back"in the fall (autumn).
现在增加一个小时,看看我们得到了什么。如果忽略 DST,我们将得到凌晨 2 点。如果遵守 DST,我们将得到凌晨 1 点……当到达凌晨 2 点时,挂钟时间跳回到凌晨 1 点,但与 UTC 有一个新的偏移。这在秋季(秋季)通俗地称为“回落”。
ZonedDateTime after = before.plusHours( 1 ); // 2 AM? Nope, 1 AM because DST Daylight Saving Time expires at 2 AM Nov 1, 2015.
Dump to console.
转储到控制台。
System.out.println( "localDateTime : " + localDateTime );
System.out.println( "localDateTimeOneHourLater : " + localDateTimeOneHourLater );
System.out.println( "before : " + before );
System.out.println( "after : " + after );
When run, we get this output. Without a time zone, 1 AM + 1 hour = 2 AM. Remember these are "local" date-time values, not UTC. They represent only the vague idea of a date-time, not an actual moment on the timeline.
运行时,我们得到这个输出。没有时区,凌晨 1 点 + 1 小时 = 凌晨 2 点。请记住,这些是“本地”日期时间值,而不是 UTC。它们仅代表日期时间的模糊概念,而不是时间线上的实际时刻。
localDateTime : 2015-11-01T01:00
localDateTimeOneHourLater : 2015-11-01T02:00
But with time zones applied on the day DST expires, we get different results. Note how the time-of-day remains 01:00
but the offset-from-UTCchanges from -07:00
to -08:00
.
但是在 DST 到期当天应用时区,我们得到不同的结果。请注意时间是如何保留的,01:00
但与UTC的偏移量从-07:00
变为-08:00
。
before : 2015-11-01T01:00-07:00[America/Los_Angeles]
after : 2015-11-01T01:00-08:00[America/Los_Angeles]
Perhaps this would more clear and easier to verify if we adjust into UTC. We can do that simply by accessing the before
and after
objects as Instant
objects. The System.out.println
then implicitly calls the toString
method.
如果我们调整到 UTC,这也许会更清楚、更容易验证。我们可以简单地通过将before
和after
对象作为Instant
对象访问来做到这一点。在System.out.println
随后隐式调用的toString
方法。
System.out.println( "before.toInstant : " + before.toInstant() );
System.out.println( "after.toInstant : " + after.toInstant() );
When run.
跑的时候。
before.toInstant : 2015-11-01T08:00:00Z
after.toInstant : 2015-11-01T09:00:00Z
About java.time
关于java.time
The java.timeframework is built into Java 8 and later. These classes supplant the troublesome old legacydate-time classes such as java.util.Date
, Calendar
, & SimpleDateFormat
.
该java.time框架是建立在Java 8和更高版本。这些类取代了麻烦的旧的遗留日期时间类,例如java.util.Date
, Calendar
, & SimpleDateFormat
。
The Joda-Timeproject, now in maintenance mode, advises migration to the java.timeclasses.
现在处于维护模式的Joda-Time项目建议迁移到java.time类。
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
要了解更多信息,请参阅Oracle 教程。并在 Stack Overflow 上搜索许多示例和解释。规范是JSR 310。
You may exchange java.timeobjects directly with your database. Use a JDBC drivercompliant with JDBC 4.2or later. No need for strings, no need for java.sql.*
classes.
您可以直接与数据库交换java.time对象。使用符合JDBC 4.2或更高版本的JDBC 驱动程序。不需要字符串,不需要类。java.sql.*
Where to obtain the java.time classes?
从哪里获得 java.time 类?
- Java SE 8, Java SE 9, Java SE 10, and later
- Built-in.
- Part of the standard Java API with a bundled implementation.
- Java 9 adds some minor features and fixes.
- Java SE 6and Java SE 7
- Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
- Android
- Later versions of Android bundle implementations of the java.timeclasses.
- For earlier Android (<26), the ThreeTenABPproject adapts ThreeTen-Backport(mentioned above). See How to use ThreeTenABP….
- Java SE 8、Java SE 9、Java SE 10及更高版本
- 内置。
- 具有捆绑实现的标准 Java API 的一部分。
- Java 9 添加了一些小功能和修复。
- Java SE 6和Java SE 7
- 多的java.time功能后移植到Java 6和7在ThreeTen-反向移植。
- 安卓
- 更高版本的 Android 捆绑实现java.time类。
- 对于早期的 Android(<26),ThreeTenABP项目采用了ThreeTen-Backport(上面提到过)。请参阅如何使用ThreeTenABP ...。
The ThreeTen-Extraproject extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval
, YearWeek
, YearQuarter
, and more.
该ThreeTen-额外项目与其他类扩展java.time。该项目是未来可能添加到 java.time 的试验场。你可能在这里找到一些有用的类,比如Interval
,YearWeek
,YearQuarter
,和更多。
回答by eugenioy
Yes, the Java API will take DST changes into account.
是的,Java API 将考虑 DST 更改。
This tutorial explains quite well how to convert dates between timezones and how to choose the right class to represent a date: https://docs.oracle.com/javase/tutorial/datetime/iso/timezones.html
本教程很好地解释了如何在时区之间转换日期以及如何选择正确的类来表示日期:https: //docs.oracle.com/javase/tutorial/datetime/iso/timezones.html
You can also look at this class which represents the rules for each zone: http://docs.oracle.com/javase/8/docs/api/java/time/zone/ZoneRules.html
您还可以查看代表每个区域的规则的类:http: //docs.oracle.com/javase/8/docs/api/java/time/zone/ZoneRules.html
In particular, this method can tell you if a particular instant is in daylight savings: http://docs.oracle.com/javase/8/docs/api/java/time/zone/ZoneRules.html#isDaylightSavings-java.time.Instant-
特别是,此方法可以告诉您某个特定时刻是否处于夏令时:http: //docs.oracle.com/javase/8/docs/api/java/time/zone/ZoneRules.html#isDaylightSavings-java.time 。立即的-