gpt4 book ai didi

java - 如何在java8中获得默认的ZoneOffset?

转载 作者:IT老高 更新时间:2023-10-28 20:48:48 27 4
gpt4 key购买 nike

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

我看到一个 ZoneId有一些“规则”,每个规则都有一个 ZoneOffset , 是否意味着 ZoneId可能有多个 ZoneOffset ?

最佳答案

tl;博士

OffsetDateTime.now().getOffset()
但是您可能应该使用时区,而不仅仅是与 UTC 的偏移量。
ZoneId.systemDefault() 
偏移与时区
offset-from-UTC只是一些小时、分钟和秒——仅此而已。例如, -08:00表示比 UTC 晚八小时,以及 +05:45表示比 UTC 提前五小时四十五分钟.
time zone偏移量的过去、现在和 future 变化的历史特定地区的人们使用。异常如 Daylight Saving Time (DST)在特定时间段内引起偏移量的变化会随着时间的推移、过去发生的变化以及 future 政治家宣布计划的变化时进行跟踪。
所以 最好使用区域 知道的时候。
任何区域的偏移量随时间变化。例如, DST in the United States在大约半年的时间内将偏移量移动一个小时,然后在一年的另一半期间将该小时恢复到偏移量。时区的全部目的是记录这些偏移量的变化。
所以真的 在没有日期时间的情况下要求偏移是没有意义的 .在 America/Los_Angeles ,例如在今年的部分时间偏移量是 -08:00但在一年的另一部分是 -07:00夏令时期间。 OffsetDateTime所以让我们指定一个时刻为 OffsetDateTime ,然后提取 ZoneOffset .
OffsetDateTime odt = OffsetDateTime.now ();
ZoneOffset zoneOffset = odt.getOffset ();

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


zoneOffset.toString(): -08:00


那个 now方法实际上是隐式应用 JVM 当前的默认时区。我建议您始终通过指定所需/预期的时区来明确说明。即使您想要当前的默认区域,也要明确说明以明确您的意图。消除关于您是否打算使用默认值或未考虑时区的歧义,就像程序员经常发生的那样。调用 ZoneId.systemDefault .
OffsetDateTime odt = OffsetDateTime.now ( ZoneId.systemDefault () );
ZoneOffset zoneOffset = odt.getOffset ();

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


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


zoneOffsetOfOdt: -08:00


关于依赖默认区域的注意事项:此默认值可以随时由 JVM 中任何线程中的任何代码更改。如果重要,请询问用户他们想要的时区。
您可以询问偏移量作为总秒数的时间量。
int offsetSeconds = zoneOffset.getTotalSeconds ();

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[America/Montreal]


zoneOffsetXmas.toString(): -05:00


zoneOffsetXmas.getTotalSeconds(): -18000


Table of date-time types in Java, both modern and legacy. ZoneId正如 yanys 在评论中所建议的,您可以询问 ZoneId 对于特定的 ZoneOffset通过作为 Instant 传递片刻. Instant class 代表时间线上的一个时刻 UTC分辨率为 nanoseconds (最多九 (9) 位小数)。
这只是通往同一目的地的另一条路线。就像 OffsetDateTimeZonedDateTime上面讨论过,我们正在指定 (a) 一个时区,和 (b) 一个时刻。
Instant instant = zdtXmas.toInstant();
ZoneOffset zo = z.getRules().getOffset( instant );

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


查看所有这些示例 code live at IdeOne.com . ZoneOffset.systemDefault – 错误或功能? ZoneOffset类, ZoneId 的子类, 被记录为继承了 systemDefault 方法。但是,这实际上不起作用。
ZoneOffset zoneOffset = ZoneOffset.systemDefault() ;  // Fails to compile.

error: incompatible types: ZoneId cannot be converted to ZoneOffset


不确定这种编译失败是错误还是功能。如上所述,对我来说,要求使用日期时间的默认偏移量似乎没有意义,所以也许 ZoneOffset.systemDefault确实应该失败。但是文档应该这样说,并有解释。
我试图提交一个关于文档未能解决这个问题的错误,但放弃了,无法确定在哪里以及如何提交这样的错误报告。
太阳时间与政治时间
关于偏移量和时区的更多信息......
Solar Time自史前以来就已被使用,通过记录太阳何时直接在头顶上来跟踪每一天。在地上戳一根棍子,观察它的影子。当影子最短,当影子开始增长而不是缩小时,你就知道现在是中午了。用 sundial 将其正式化跟踪小时通过。
随着太阳时,当你从一个城镇到另一个城镇向西移动时,中午会晚一点到达。继续往东走,中午来得早一些。所以每个城镇都有自己的中午,只与同一经度的南北城镇共享。
在现代,太阳时间在很大程度上被放弃了。随着火车、电报和电话的到来,时间协调的需要也随之而来。因此,选择了一个接近太阳时正午的点,并宣布向西和向东如此多英里的大片土地在时钟上共享相同的 12:00, Greenwich Prime Meridian 之前或之后偏移相同的小时数线路 .于是开始了在每个火车停靠站显眼地展示时钟的传统,让镇上知道 standard time对于他们更大的地区,而不是他们自己城镇的太阳时。通常,该时区西部边缘的城镇会在太阳升起之前看到他们的火车站时钟显示为 12:00。在太阳升起后不久,该地区东部边缘城镇的时钟显示为 12:00。
世界各地的政客都表现出改变其管辖范围的倾向。原因各不相同,外交、 war 和占领,还有 Daylight Saving Time (DST)的愚蠢。 .原因各不相同,但它们的变化以惊人的频率出现。时区是一个区域的名称,用于跟踪其此类变化的历史。所以一个 offset-from-UTC仅仅是小时-分钟-秒的数量 在本初子午线之前或之后。 A 时区更多:历史特定区域偏移量的过去、现在和 future 变化。虽然今天两个相邻地区可能共享相同的 UTC 偏移量,但在过去或 future ,它们可能会因政治家的不同想法或逻辑而有所不同。
这意味着政治家定义的现代时间跟踪与地理无关。例如,今天印度这个巨大的国家有一个单一的时区(UTC 偏移量 +05:30)。因此,在广阔的次大陆的各个地方,太阳正午(太阳直接在您的头顶上)相隔数小时。印度的政客们决定这样做是为了帮助统一他们多元化的民主。在世界各地的其他例子中,我们看到地区使用它们的时区作为国际关系的象征,例如不同于它们的邻国,或者选择与邻国相同的区域作为最近在朝鲜看到的关系解冻改变以匹配韩国。因此,如今,太阳时只是时间跟踪的几个考虑因素之一。

关于 java.time
java.time框架内置于 Java 8 及更高版本中。这些类取代了麻烦的旧 legacy日期时间类,例如 java.util.Date , Calendar , & SimpleDateFormat .
要了解更多信息,请参阅 Oracle Tutorial .并在 Stack Overflow 上搜索许多示例和解释。规范为 JSR 310 .
Joda-Time项目,现在在 maintenance mode ,建议迁移到 java.time类。
您可以直接与您的数据库交换 java.time 对象。使用 JDBC driver符合 JDBC 4.2或以后。不需要字符串,不需要 java.sql.*类。 Hibernate 5 & JPA 2.2 支持 java.time。
从哪里获得 java.time 类?
  • Java SE 8 , Java SE 9 , Java SE 10 , Java SE 11 , and later - 标准 Java API 的一部分,具有捆绑的实现。
  • Java 9带来了一些小功能和修复。

  • Java SE 6Java SE 7
  • 大多数 java.time 功能在 ThreeTen-Backport 中向后移植到 Java 6 和 7。 .

  • Android
  • 更高版本的 Android (26+) 捆绑了 java.time 类的实现。
  • 对于早期的 Android (<26),一个称为 API desugaring 的进程带来了 subset of the java.time最初未内置于 Android 中的功能。
  • 如果脱糖不能满足您的需求,ThreeTenABP项目适应 ThreeTen-Backport (上面提到的)到Android。见 How to use ThreeTenABP… .



  • Table of which java.time library to use with which version of Java or Android

    关于java - 如何在java8中获得默认的ZoneOffset?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41427384/

    27 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com