Java 10与Java 8中从毫秒自历元到LocalDateTime的日期转换
我有一个应用程序,我使用从Epoch开始的毫秒数转换为LocalDateTime,然后再转换回来。该应用程序在Java8上运行良好,但我尝试更新到Java10,发现了以下问题
这是Java8中的输出
✘ magg@MacBook-Pro-de-Miguel ~/Desktop/CODE java TimeTest
2018-09-06T20:13:30.253
1536290010253
2018-09-06T20:13:30.253
✘ magg@MacBook-Pro-de-Miguel ~/Desktop/CODE java -version
java version "1.8.0_181"
Java(TM) SE Runtime Environment (build 1.8.0_181-b13)
Java HotSpot(TM) 64-Bit Server VM (build 25.181-b13, mixed mode)
这是Java10中的输出,如果您看到格式的末尾是6位,而不是像Java8中的3位,那么这将中断从历元到LocalDateTime的毫秒转换
✘ magg@MacBook-Pro-de-Miguel ~/Desktop/CODE java TimeTest
2018-09-06T20:13:18.568414
1536289998568
2018-09-06T20:13:18.568
✘ magg@MacBook-Pro-de-Miguel ~/Desktop/CODE java -version
java version "10.0.2" 2018-07-17
Java(TM) SE Runtime Environment 18.3 (build 10.0.2+13)
Java HotSpot(TM) 64-Bit Server VM 18.3 (build 10.0.2+13, mixed mode)
这是源代码
public class TimeTest{
public static void main(String[] args)
{
TimeZone.setDefault(TimeZone.getTimeZone("America/Los_Angeles"));
LocalDateTime issueTime = LocalDateTime.now();
System.out.println(issueTime.toString());
ZonedDateTime zdt = issueTime.atZone(TimeZone.getDefault().toZoneId());
long timeInMillis = zdt.toInstant().toEpochMilli();
System.out.println(timeInMillis );
LocalDateTime date = LocalDateTime.ofInstant(Instant.ofEpochMilli(timeInMillis), TimeZone.getDefault().toZoneId());
System.out.println(date.toString());
}
}
如何在Java10中修复此问题
# 1 楼答案
首先,来自
LocalDateTime.toString()
的输出不是固定长度的。从其Javadoc(从8到10不变):您的Java 10运行碰巧打印了带六位小数的秒值,但它可能打印了带三位小数或九位小数的秒值,这取决于几个因素:
now()
返回的实际值李>从统计学上讲,用小数点后三位而不是六位来表示是不可能的,但绝对有可能的。如果您的硬件支持,则更可能需要9位小数,而不是6位小数。当我在Java10下运行代码时,通常会打印九位小数,但偶尔只需要六位小数
其次,在Java 9中,“Java.time.Clock”返回的系统时钟被更改,因此它们提供的精度至少与系统上可用的底层时钟相同”。请参阅JDK-8068730 Increase the precision of the implementation of java.time.Clock.systemUTC(),其中明确说明了您的情况:
关于您的问题“我如何在Java 10中修复此问题?”,我不确定您想要修复什么,因为我不知道您的应用程序需求的详细信息
teppic的一条评论已经解释了如何使用
LocalDateTime.now().truncatedTo(ChronoUnit.MILLIS)
将精度限制在小数点后三位,但我不认为这样做有什么好处,除非应用程序要求固定精度为小数点后三位。另一种方法可能是使用纳米精度,如有必要,将零焊盘设置为九位数;这样,您将获得更高精度的好处,但仍然具有固定的长度值