tl;dr
OffsetDateTime.now().getOffset()
但您可能应该使用时区而不是仅仅偏离UTC。
ZoneId.systemDefault()
Offset versus Time Zone
offset-from-UTC只是一小时,几分钟和几秒钟 - 仅此而已。
time zone是特定地区人民使用的偏移的过去,现在和未来变化的历史。时区有一组规则来处理诸如Daylight Saving Time (DST)之类的异常,这些异常会导致特定时间段内偏移的变化。
时区=(偏移历史+异常规则)
因此,在知道时更好地使用区域。
任何地区的偏移量随时间而变化。例如,DST in the United States将偏移量移动一个小时,大约一半,然后在一年的另一半中将该小时恢复到偏移量。时区的整个目的是记录偏移量的变化。
因此,在没有日期时间的情况下要求偏移是没有意义的。在America/Los_Angeles,例如在今年的部分时间,补偿是-08:00,但在夏令时期间的另一部分是-07:00。
OffsetDateTime
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
自: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 [美国/蒙特利尔]
zoneOffsetXmas.toString(): - 05:00
zoneOffsetXmas.getTotalSeconds(): - 18000
ZoneId
正如yanys的评论中所建议的,你可以通过传递一个时刻作为ZoneId来查询ZoneOffset特定的Instant。 Instant类代表UTC时间轴上的一个时刻,分辨率为nanoseconds(小数部分最多九(9)位)。
这只是通往同一目的地的另一条路线。就像上面讨论的OffsetDateTime和ZonedDateTime一样,我们指定(a)时区,(b)片刻。
Instant instant = zdtXmas.toInstant();
ZoneOffset zo = z.getRules().getOffset( instant );
对于ZoneId:美国/蒙特利尔立即:2017-12-25T05:00:00Z ZoneOffset为:-05:00
ZoneOffset.systemDefault - 错误或功能?
ZoneOffset类是ZoneId的子类,记录为继承systemDefault方法。但是,这实际上并不起作用。
ZoneOffset zoneOffset = ZoneOffset.systemDefault() ; // Fails to compile.
错误:不兼容的类型:ZoneId无法转换为ZoneOffset
不确定这个编译失败是错误还是功能。如上所述,对于我来说,要求使用日期时间的默认偏移似乎没有意义,所以也许ZoneOffset.systemDefault确实会失败。但文档应该这样说,并附上解释。
我试图提交一个关于文档无法解决此问题的错误,但放弃了,无法确定在何处以及如何提交此类错误报告。
About java.time
要了解更多信息,请参阅Oracle Tutorial。并搜索Stack Overflow以获取许多示例和解释。规格是JSR 310。
您可以直接与数据库交换java.time对象。使用符合JDBC driver或更高版本的JDBC 4.2。不需要字符串,不需要java.sql.*类。
从哪里获取java.time类?
Java SE 8,Java SE 9,Java SE 10,Java SE 11和更高版本 - 带有捆绑实现的标准Java API的一部分。
Java 9增加了一些小功能和修复。
Android
更高版本的Android捆绑java.time类的实现。
对于早期的Android(<26),ThreeTenABP项目适应ThreeTen-Backport(如上所述)。见How to use ThreeTenABP…。
ThreeTen-Extra项目使用其他类扩展了java.time。该项目是未来可能添加到java.time的试验场。你可能会在这里找到一些有用的类,如Interval,YearWeek,YearQuarter和more。