草庐IT

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

coder 2023-05-14 原文

使用 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


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… .



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

    有关java - 如何在java8中获得默认的ZoneOffset?的更多相关文章

    1. ruby - 如何在 Ruby 中顺序创建 PI - 2

      出于纯粹的兴趣,我很好奇如何按顺序创建PI,而不是在过程结果之后生成数字,而是让数字在过程本身生成时显示。如果是这种情况,那么数字可以自行产生,我可以对以前看到的数字实现垃圾收集,从而创建一个无限系列。结果只是在Pi系列之后每秒生成一个数字。这是我通过互联网筛选的结果:这是流行的计算机友好算法,类机器算法:defarccot(x,unity)xpow=unity/xn=1sign=1sum=0loopdoterm=xpow/nbreakifterm==0sum+=sign*(xpow/n)xpow/=x*xn+=2sign=-signendsumenddefcalc_pi(digits

    2. ruby - 如何在 buildr 项目中使用 Ruby 代码? - 2

      如何在buildr项目中使用Ruby?我在很多不同的项目中使用过Ruby、JRuby、Java和Clojure。我目前正在使用我的标准Ruby开发一个模拟应用程序,我想尝试使用Clojure后端(我确实喜欢功能代码)以及JRubygui和测试套件。我还可以看到在未来的不同项目中使用Scala作为后端。我想我要为我的项目尝试一下buildr(http://buildr.apache.org/),但我注意到buildr似乎没有设置为在项目中使用JRuby代码本身!这看起来有点傻,因为该工具旨在统一通用的JVM语言并且是在ruby中构建的。除了将输出的jar包含在一个独特的、仅限ruby​​

    3. ruby - 什么是填充的 Base64 编码字符串以及如何在 ruby​​ 中生成它们? - 2

      我正在使用的第三方API的文档状态:"[O]urAPIonlyacceptspaddedBase64encodedstrings."什么是“填充的Base64编码字符串”以及如何在Ruby中生成它们。下面的代码是我第一次尝试创建转换为Base64的JSON格式数据。xa=Base64.encode64(a.to_json) 最佳答案 他们说的padding其实就是Base64本身的一部分。它是末尾的“=”和“==”。Base64将3个字节的数据包编码为4个编码字符。所以如果你的输入数据有长度n和n%3=1=>"=="末尾用于填充n%

    4. ruby-on-rails - 如何在 ruby​​ 中使用两个参数异步运行 exe? - 2

      exe应该在我打开页面时运行。异步进程需要运行。有什么方法可以在ruby​​中使用两个参数异步运行exe吗?我已经尝试过ruby​​命令-system()、exec()但它正在等待过程完成。我需要用参数启动exe,无需等待进程完成是否有任何ruby​​gems会支持我的问题? 最佳答案 您可以使用Process.spawn和Process.wait2:pid=Process.spawn'your.exe','--option'#Later...pid,status=Process.wait2pid您的程序将作为解释器的子进程执行。除

    5. ruby - 默认情况下使选项为 false - 2

      这是在Ruby中设置默认值的常用方法:classQuietByDefaultdefinitialize(opts={})@verbose=opts[:verbose]endend这是一个容易落入的陷阱:classVerboseNoMatterWhatdefinitialize(opts={})@verbose=opts[:verbose]||trueendend正确的做法是:classVerboseByDefaultdefinitialize(opts={})@verbose=opts.include?(:verbose)?opts[:verbose]:trueendend编写Verb

    6. ruby - 如何在续集中重新加载表模式? - 2

      鉴于我有以下迁移:Sequel.migrationdoupdoalter_table:usersdoadd_column:is_admin,:default=>falseend#SequelrunsaDESCRIBEtablestatement,whenthemodelisloaded.#Atthispoint,itdoesnotknowthatusershaveais_adminflag.#Soitfails.@user=User.find(:email=>"admin@fancy-startup.example")@user.is_admin=true@user.save!ende

    7. ruby - 如何在 Ruby 中拆分参数字符串 Bash 样式? - 2

      我正在为一个项目制作一个简单的shell,我希望像在Bash中一样解析参数字符串。foobar"helloworld"fooz应该变成:["foo","bar","helloworld","fooz"]等等。到目前为止,我一直在使用CSV::parse_line,将列分隔符设置为""和.compact输出。问题是我现在必须选择是要支持单引号还是双引号。CSV不支持超过一个分隔符。Python有一个名为shlex的模块:>>>shlex.split("Test'helloworld'foo")['Test','helloworld','foo']>>>shlex.split('Test"

    8. ruby - 如何在 Lion 上安装 Xcode 4.6,需要用 RVM 升级 ruby - 2

      我实际上是在尝试使用RVM在我的OSX10.7.5上更新ruby,并在输入以下命令后:rvminstallruby我得到了以下回复:Searchingforbinaryrubies,thismighttakesometime.Checkingrequirementsforosx.Installingrequirementsforosx.Updatingsystem.......Errorrunning'requirements_osx_brew_update_systemruby-2.0.0-p247',pleaseread/Users/username/.rvm/log/138121

    9. java - 等价于 Java 中的 Ruby Hash - 2

      我真的很习惯使用Ruby编写以下代码:my_hash={}my_hash['test']=1Java中对应的数据结构是什么? 最佳答案 HashMapmap=newHashMap();map.put("test",1);我假设? 关于java-等价于Java中的RubyHash,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/22737685/

    10. ruby-on-rails - date_field_tag,如何设置默认日期? [ rails 上的 ruby ] - 2

      我想设置一个默认日期,例如实际日期,我该如何设置?还有如何在组合框中设置默认值顺便问一下,date_field_tag和date_field之间有什么区别? 最佳答案 试试这个:将默认日期作为第二个参数传递。youcorrectlysetthedefaultvalueofcomboboxasshowninyourquestion. 关于ruby-on-rails-date_field_tag,如何设置默认日期?[rails上的ruby],我们在StackOverflow上找到一个类似的问

    随机推荐