如何在java8中获取默认的ZoneOffset? [英] How to get default ZoneOffset in java8?

查看:165
本文介绍了如何在java8中获取默认的ZoneOffset?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用java8,我们知道使用 ZoneId.default()可以获得系统默认 ZoneId ,但是如何获取默认值 ZoneOffset

With java8 we know use ZoneId.default() can get system default ZoneId, but how to get default ZoneOffset?

我看到 ZoneId 有一些规则,每条规则都有 ZoneOffset ,这意味着 ZoneId 可能有多个 ZoneOffset

I see that a ZoneId has some "rules" and each rule has a ZoneOffset, is that means a ZoneId may have more than one ZoneOffset?

推荐答案

tl; dr



tl;dr

OffsetDateTime.now().getOffset()



抵消与时区



抵消 - UTC 仅仅是一小时,分钟和秒 - 仅此而已。

Offset versus Time Zone

An offset-from-UTC is merely a number of hour, minutes, and seconds — nothing more.

A 时区是特定区域的偏移历史加上一组处理异常的规则,例如 Daylight Savin g时间(DST)导致偏移在特定时间段内发生变化。

A time zone is a history of offsets for a particular region plus a set of rules to handle anomalies such as Daylight Saving Time (DST) that cause shifts in the offset over specific periods of time.

时区=(偏移历史+规则) -for-anomalies)

所以在知道时更好地使用区域

任何地区的偏移量随时间而变化。例如,美国的DST 将偏移量移动一小时,大约一半,然后在一年的另一半恢复那个小时回到抵消。时区的整个目的是记录那些偏移的变化。

The offset for any region varies over time. For example, DST in the United States shifts the offset by an hour for about half the year and then restoring that hour back to the offset during the other half of the year. The entire purpose of a time zone is to document those shifts in offset.

所以真的没有理由要求没有日期时间的偏移即可。在 America / Los_Angeles 中,例如今年的部分时间偏移量是 -08:00 ,但在一年的另一部分,它在夏令时期间 -07:00

So it really makes no sense to ask for an offset without a date-time. In America/Los_Angeles, for example in part of this year the offset is -08:00 but in another part of the year it is -07:00 during DST.

所以让我们指定一个时刻作为 OffsetDateTime ,然后提取 ZoneOffset

So let's specify a moment as an OffsetDateTime, and then extract the ZoneOffset.

OffsetDateTime odt = OffsetDateTime.now ();
ZoneOffset zoneOffset = odt.getOffset ();




odt.toString():2017-01-02T15:19: 47.162-08:00

odt.toString(): 2017-01-02T15:19:47.162-08:00

zoneOffset.toString(): - 08:00

zoneOffset.toString(): -08:00

now 方法实际上是隐式应用JVM的当前默认时区。我建议您始终通过指定所需/预期的时区来明确说明。即使你想要当前的默认区域,也要明确说明你的意图。消除关于您是否打算使用默认值或未能考虑时区的模糊性,因为程序员经常会这样做。请致电 ZoneId。 systemDefault

That now method is actually applying implicitly the JVM’s current default time zone. I suggest you always make that explicit by specifying your desired/expected time zone. Even if you want the current default zone, say so explicitly to make your intentions clear. Eliminate the ambiguity about whether you intended the default or failed to consider time zone as so often happens with programmers. Call ZoneId.systemDefault.

OffsetDateTime odt = OffsetDateTime.now ( ZoneId.systemDefault () );
ZoneOffset zoneOffset = odt.getOffset ();




ZoneId.systemDefault()。toString():America / Los_Angeles

ZoneId.systemDefault().toString(): America/Los_Angeles

odt:2017-01-02T15:19:47.162-08:00

odt: 2017-01-02T15:19:47.162-08:00

zoneOffsetOfOdt:-08:00

zoneOffsetOfOdt: -08:00

关于依赖默认区域的注意事项:JVM中任何线程中的任何代码都可以随时更改此默认值。如果重要,请询问用户预期的时区。

A caution about depending on the default zone: This default can be changed at any moment by any code in any thread within the JVM. If important, ask the user for their intended time zone.

您可以将偏移量作为总秒数询问偏差。

You can ask the offset for its amount of time as a total number of seconds.

int offsetSeconds = zoneOffset.getTotalSeconds ();




offsetSeconds:-28800

offsetSeconds: -28800



ZonedDateTime



另一个例子:也许你想知道今年圣诞节那天在魁北克会有什么抵消。指定时区 America / Montreal ,获取 ZonedDateTime ,要求将其偏移量作为 ZoneOffset 对象。

ZoneId z = ZoneId.of( "America/Montreal" );
LocalDate ld = LocalDate.of( 2017 , 12 , 25 );
ZonedDateTime zdtXmas = ld.atStartOfDay( z );
ZoneOffset zoneOffsetXmas = zdtXmas.getOffset();




zdtXmas.toString():2017-12-25T00:00- 05:00 [美国/蒙特利尔]

zdtXmas.toString(): 2017-12-25T00:00-05:00[America/Montreal]

zoneOffsetXmas.toString(): - 05:00

zoneOffsetXmas.toString(): -05:00

zoneOffsetXmas。 getTotalSeconds(): - 18000

zoneOffsetXmas.getTotalSeconds(): -18000



ZoneId



根据yanys的评论中的建议,您可以查询 ZoneOffset 的rel =noreferrer> ZoneId ,将一个时刻作为<$传递C $ C>即时。 Instant class代表 UTC 中时间轴上的一个时刻,分辨率为纳秒(小数部分最多九(9)位)。

ZoneId

As suggested in the comment by yanys, you can interrogate a ZoneId for a particular ZoneOffset by passing a moment as an Instant. The Instant class represents a moment on the timeline in UTC with a resolution of nanoseconds (up to nine (9) digits of a decimal fraction).

这只是通往同一目的地的另一条路线。就像上面讨论的 OffsetDateTime ZonedDateTime 一样,我们指定(a)时区,(b)a时刻。

This is just another route to the same destination. Just like with OffsetDateTime and ZonedDateTime discussed above, we are specifying (a) a time zone, and (b) a moment.

Instant instant = zdtXmas.toInstant();
ZoneOffset zo = z.getRules().getOffset( instant );




对于ZoneId:美国/蒙特利尔时刻:2017-12-25T05 :00:00Z ZoneOffset是:-05:00

For ZoneId: America/Montreal at instant: 2017-12-25T05:00:00Z the ZoneOffset is: -05:00

查看所有这些示例'代码在IdeOne.com上发布

ZoneOffset 类, ZoneId的子类,记录为继承 systemDefault 方法。但是,这实际上并不起作用。

The ZoneOffset class, a subclass of ZoneId, is documented as inheriting the systemDefault method. However, this does not actually work.

ZoneOffset zoneOffset = ZoneOffset.systemDefault() ;  // Fails to compile.




错误:不兼容的类型:ZoneId无法转换为ZoneOffset

error: incompatible types: ZoneId cannot be converted to ZoneOffset

不确定此编译失败是否是错误或功能。如上所述,对于我来说,使用日期时间要求默认偏移量似乎没有意义,所以 ZoneOffset.systemDefault 可能确实会失败。但文档应该这样说,并附上解释。

Not sure if this failure-to-compile is a bug or a feature. As discussed above, it does not seem to make sense to me to ever ask for default offset with a date-time, so perhaps the ZoneOffset.systemDefault should indeed fail. But the documentation should say so, with an explanation.

我试图提交一份关于文档未能解决此问题的错误,但放弃了,无法确定在何处以及如何提交此类错误报告。

I tried to file a bug on the failure of the doc to address this issue, but gave up, unable to determine where and how to file such a bug report.

java.time 框架内置于Java 8及更高版本中。这些类取代了麻烦的旧遗留日期时间类,例如 java.util.Date 日历 ,& SimpleDateFormat

The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.

Joda-Time 项目,现在位于维护模式,建议迁移到 java.time 课程。

The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.

要了解更多信息,请参阅 Oracle教程 。并搜索Stack Overflow以获取许多示例和解释。规范是 JSR 310

To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.

您可以直接与数据库交换 java.time 对象。使用符合 JDBC驱动程序 jeps / 170rel =noreferrer> JDBC 4.2 或更高版本。不需要字符串,不需要 java.sql。* 类。

You may exchange java.time objects directly with your database. Use a JDBC driver compliant with JDBC 4.2 or later. No need for strings, no need for java.sql.* classes.

从哪里获取java.time班?

Where to obtain the java.time classes?


  • Java SE 8 Java SE 9 Java SE 10 Java SE 11 以及更高版本 - 标准Java API的一部分捆绑式实施。


    • Java 9增加了一些小功能和修复。

    • Java SE 8, Java SE 9, Java SE 10, Java SE 11, and later - Part of the standard Java API with a bundled implementation.
      • Java 9 adds some minor features and fixes.
      • Most of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
      • Later versions of Android bundle implementations of the java.time classes.
      • For earlier Android (<26), the ThreeTenABP project adapts ThreeTen-Backport (mentioned above). See How to use ThreeTenABP….

      ThreeTen-Extra 项目使用其他类扩展了java.time。该项目是未来可能添加到java.time的试验场。您可以在这里找到一些有用的课程,例如 间隔 YearWeek YearQuarter 更多

      这篇关于如何在java8中获取默认的ZoneOffset?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆