tl;博士
Instant.EPOCH.plus(
Duration.ofNanos(
TimeUnit.MICROSECONDS.toNanos(
Long.parse( "1474457086337977" ) ) ) )
java.time
java.time 类支持nanoseconds 的分辨率,对于您的microseconds 来说绰绰有余。
解析数字字符串
将字符串解析为long,以获取纪元的微秒计数。
long micros = Long.parse( "1474457086337977" );
当然,您总是可以使用整数文字。注意 L 附加到整数文字。
long micros = 1_474_457_086_337_977L ;
将 long 转换为 Instant
我们希望将微秒计数从 UTC 1970 年初的 epoch (1970-01-01T00:00:00Z) 转换为 Instant。 Instant 类代表UTC 时间线上的一个时刻,分辨率为nanoseconds。这意味着最多九位小数。
Instant 类具有方便的静态方法,用于从 count of whole seconds、count of whole seconds plus a fractional second in nanoseconds 或 count of milliseconds 进行转换。但不幸的是,没有这样的方法可以计算微秒或纳秒。
作为一种解决方法,我们可以定义一个Duration 并将其添加到已经定义为常量的纪元参考日期。我们可以将Duration 实例化为纳秒数。为了获得纳秒,我们将您的微秒乘以一千。请注意使用 64 位 long 而不是 32 位 int。
Duration duration = Duration.ofNanos( micros * 1_000L );
Instant instant = Instant.EPOCH.plus( duration );
instant.toString(): 2016-09-21T11:24:46.337977Z
或者,您可以使用TimeUnit 枚举将微秒转换为纳秒,而无需硬编码“幻数”。
Duration duration = Duration.ofNanos( TimeUnit.MICROSECONDS.toNanos( micros ) );
要调整到其他偏移量或时区,请在 StackOverflow 中搜索 Java 类 OffsetDateTime 或 ZonedDateTime。
转换为旧的日期时间类型
您应该避免与最早的 Java 版本捆绑在一起的旧日期时间类型。事实证明,它们设计不良、混乱且麻烦。现在被 java.time 类型所取代。
但如果您必须与尚未更新为 java.time 类型的旧代码进行交互,您可以转换为 java.time 或从 java.time 转换。查看添加到旧类的新方法。
java.sql.Timestamp ts = java.sql.Timestamp.from( instant );
从 java.time 类型转换为 java.util.Date 或 java.util.Calendar 时请注意数据丢失。这些类型仅解析为milliseconds。从纳秒到毫秒的截断是静默执行的,去掉小数秒的最后六个(九个)可能的数字。
java.util.Date utilDate = java.util.Date.from( instant ); // Caution: Data loss in truncating nanoseconds to milliseconds.
关于java.time
java.time 框架内置于 Java 8 及更高版本中。这些类取代了麻烦的旧日期时间类,例如 java.util.Date、.Calendar 和 java.text.SimpleDateFormat。
Joda-Time 项目现在位于maintenance mode,建议迁移到 java.time。
要了解更多信息,请参阅Oracle Tutorial。并在 Stack Overflow 上搜索许多示例和解释。
大部分 java.time 功能在ThreeTen-Backport 中向后移植到Java 6 和7,并进一步适应ThreeTenABP 中的Android(请参阅How to use…)。
ThreeTen-Extra 项目通过附加类扩展了 java.time。该项目是未来可能添加到 java.time 的试验场。