我有一个epoch秒和一个zoneId,方法1.它可以用系统默认的zoneId转换为LocalDateTime,但我找不到方法2将epoch第二个转换为LocalDateTime,因为没有ZoneOffset.systemDefault
。我认为它是模糊的。
import java.time.{Instant, LocalDateTime, ZoneId, ZoneOffset}
val epochSecond = System.currentTimeMillis() / 1000
LocalDateTime.ofInstant(Instant.ofEpochSecond(epochSecond), ZoneId.systemDefault())//method1
LocalDateTime.ofEpochSecond(epochSecond, 0, ZoneOffset.MAX)//method2
以下是如何从ZoneOffset
获得ZoneId
:
Instant instant = Instant.now(); //can be LocalDateTime
ZoneId systemZone = ZoneId.systemDefault(); // my timezone
ZoneOffset currentOffsetForMyZone = systemZone.getRules().getOffset(instant);
注意:根据时间点和特定地点的历史,ZoneId
可以有不同的偏移量。因此,选择不同的Instants会导致不同的偏移。
没有一对一的映射。 ZoneId定义了一段时间内使用一组不同ZoneOffsets的地理范围。如果时区使用夏令时,则其ZoneOffset在夏季和冬季之间会有所不同。
此外,夏令时规则可能随着时间的推移而发生变化,因此ZoneOffset可能会因此而异。 2015年10月13日与1980年10月13日相比。
因此,您只能在特定的Instant上找到ZoneId的ZoneOffset。
ZonedDateTime.now(
ZoneId.of( "America/Montreal" )
)
...当前默认时区...
ZonedDateTime.now(
ZoneId.systemDefault()
)
Answer by Stanislav Bshkyrtsev正确并直接回答您的问题。
但是,正如Answer by Jon Skeet所建议的那样,涉及的问题更多。
LocalDateTime
我没有找到将epoch second转换为LocalDateTime的方法
LocalDateTime
故意没有时区概念或从UTC偏移。不太可能你想要的。 Local…
意味着任何地方,而不是任何一个特定的地方。这个类不代表片刻,只是在大约26-27小时(全球各个时区范围)范围内的潜在时刻。
Instant
如果您想获得当前时间,则无需以纪元秒开始。获取当前的Instant
。 Instant
类代表UTC时间轴上的一个时刻,分辨率为nanoseconds(小数部分最多九(9)位)。
Instant instant = Instant.now();
在Instant
内部是nanoseconds从epoch的计数。但我们并不在乎。
ZonedDateTime
如果你想通过特定区域的挂钟时间镜头看到那个时刻,请使用ZoneId
来获得ZonedDateTime
。
ZoneId z = ZoneId.of( "Europe/Paris" );
ZonedDateTime zdt = instant.atZone( z );
作为捷径,您可以直接进行ZonedDateTime
。
ZonedDateTime zdt = ZonedDateTime.now( z );
一个ZonedDateTime
里面有一个Instant
。打电话给zdt.toInstant()
以获得与UTC基本值相同的时刻。相同数量的纳秒 - 自上世纪以来,作为ZonedDateTime
或Instant
。
如果给你一个秒数 - 从纪元开始,并且这个纪元是1970年UTC(1970-01-01T00:00:00Z
)的第一个时刻,那么将这个数字提供给Instant
。
long secondsSinceEpoch = 1_484_063_246L ;
Instant instant = Instant.ofEpochSecond( secondsSinceEpoch ) ;
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.*
类。
从哪里获取java.time类?
ThreeTen-Extra项目使用其他类扩展了java.time。该项目是未来可能添加到java.time的试验场。你可能会在这里找到一些有用的类,如Interval
,YearWeek
,YearQuarter
和more。
正如documentation所说,“这主要用于低级转换,而不是一般的应用程序使用。”
经过Instant
对我来说非常有意义 - 你的第二纪元实际上是Instant
的不同表现形式,所以转换为Instant
然后将其转换为特定的时区。
我希望下面的解决方案的前两行是有用的。我的问题是我有一个LocalDateTime
和一个时区的名称,我需要一个instant
所以我可以建立一个java.util.Date
,因为这是MongoDB想要的。我的代码是Scala,但它与Java如此接近,我认为理解它应该没有问题:
val zid = ZoneId.of(tzName) // "America/Los_Angeles"
val zo: ZoneOffset = zid.getRules.getOffset(localDateTime) // ⇒ -07:00
// 2017-03-16T18:03
val odt = OffsetDateTime.of(localDateTime, zo) // ⇒ 2017-03-16T18:03:00-07:00
val instant = odt.toInstant // ⇒ 2017-03-17T01:03:00Z
val issued = Date.from(instant)
以下命令返回添加到UTC以获取此时区的标准时间的时间量(以毫秒为单位):
TimeZone.getTimeZone(ZoneId.of("Europe/Amsterdam")).getRawOffset()