Kla*_*aus 3 java date java-8 java-10 localdate
我有一个应用程序,我使用毫秒自Epoch转换为LocalDateTime和返回,该应用程序在Java 8上运行良好,但我尝试更新到Java 10,并发现以下问题
这是Java 8中的输出
? 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)
Run Code Online (Sandbox Code Playgroud)
这是Java 10中的输出,如果你看到格式是6位数字,而不是像Java 8中的那样,这打破了从Epoch到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)
Run Code Online (Sandbox Code Playgroud)
这是源代码
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());
}
}
Run Code Online (Sandbox Code Playgroud)
我如何在Java 10中解决这个问题?
首先,输出LocalDateTime.toString()不是固定长度.从它的Javadoc(从8到10不变):
public String toString()
Outputs this date-time as a String, such as 2007-12-03T10:15:30.
The output will be one of the following ISO-8601 formats:
uuuu-MM-dd'T'HH:mm
uuuu-MM-dd'T'HH:mm:ss
uuuu-MM-dd'T'HH:mm:ss.SSS
uuuu-MM-dd'T'HH:mm:ss.SSSSSS
uuuu-MM-dd'T'HH:mm:ss.SSSSSSSSS
The format used will be the shortest that outputs the full value of the time where the omitted parts are implied to be zero.
Run Code Online (Sandbox Code Playgroud)
您的Java 10运行恰好打印了六位小数的秒值,但它可能打印了三位小数或九位小数,具体取决于以下几个因素:
now().它在统计上不太可能,但绝对可能的是,它可以仅使用三个小数位而不是六位来表示.如果您的硬件支持,则更有可能需要9位小数而不是6位.当我在Java 10下运行你的代码时,通常会打印九个小数位,但偶尔只需要六个小数位.
其次,在Java 9中,"java.time.Clock返回的系统时钟"被"改为",因此它们提供的精度至少与系统上可用的基础时钟相同".请参阅JDK-8068730增加java.time.Clock.systemUTC()的实现精度,它明确地解决了您的情况:
假设这些系统工厂方法返回的时钟总是具有毫秒精度并且主动依赖于它的应用程序因此可能需要更新,以便考虑更高分辨率的可能性......
关于您的问题"如何在Java 10中修复此问题?" ,我不确定你想要修复什么,因为我不知道你的应用程序要求的细节.
来自teppic的评论已经解释了如何使用精确到精确到三位小数LocalDateTime.now().truncatedTo(ChronoUnit.MILLIS),但我没有看到这样做的好处,除非你有一个固定精度为三位小数的应用程序要求.另一种方法可能是使用纳米精度,如果需要,可以使用零填充到九位数; 那么你将获得更高精度的好处,但仍然有固定的长度值.