Java 8 LocalDateTime.now()仅提供毫秒精度

ann*_*iid 7 java clock

在Java 8中可以获得微秒吗?Java 8 LocalDateTime类有一个.getNano()方法可以返回nanoseconds,但在Linux(Ubuntu)和OS X(10.11.5)上它只返回milliseconds(当我运行它返回时301000000等于301 milliseconds)并且我真的需要能够获得microseconds.

我知道有可能在我的计算机上获取nanoseconds(因此得到microseconds它),因为javascript方法process.hrtime()返回一个精确的值.

在任何人开始精确与准确的论证之前,我知道线程之间的纳秒是完全不可靠的,不应该用于比较.

编辑:

要清楚,LocalDateTime该类是Java 8类的一部分java.time.

更新:

所以我意识到Javascript process.hrtime就像Java一样System.nanoTime(),实际上与挂钟没有关系,因为它是两个语言之间不同的任意值.

新问题:有没有办法可以解析这些值的时钟时间?IE浏览器.如果我System.currentTimeMillis()System.nanoTime(),和比较,另一组这些值的我能得到第二组值的实际时间?

我的问题是我需要使用Java和Javascript进行日志记录,并且需要在两者之间都有一致的微秒字段.

Bas*_*que 14

TL;博士

在Java 8中可以获得微秒吗?

不可以.使用Java 9或更高版本.

Instant.now()  // Returns a value in microseconds in Java 9 and later, but is restricted to mere milliseconds in Java 8.
Run Code Online (Sandbox Code Playgroud)

这是指Java 8/9的Oracle和OpenJDK实现.其他可能不同.

Java 9及更高版本

Java 9有一个全新的实现,java.time.Clock能够以超过毫秒(三位小数的三位数)的分辨率捕获当前时刻.

实际分辨率取决于主机硬件时钟的限制.在Mac OS塞拉与甲骨文的Java 9.0.4,我正在用微秒当前时刻(6个小数的位数).

Instant.now().toString()
Run Code Online (Sandbox Code Playgroud)

2018-03-09T21:03:33.831515Z

Java 8

java.time类是Java 8中的新类.这些类被定义为携带纳秒(小数部分的位数).但捕获当前时刻仅限于毫秒.

2018-03-09T21:03:33.831Z

其他问题

System.currentTimeMillis()

如果我得到System.currentTimeMillis()和System.nanoTime()

无需System.currentTimeMillis()再次使用.而是java.time.Instant在UTC中使用片刻,分辨率可达纳秒级.

如果您确实需要从1970-01-01T00:00Z的纪元参考开始计算毫秒数,请询问该Instant对象.请注意数据丢失,因为您将忽略数据中存在的任何微秒或纳秒Instant.

long millisSinceEpoch = instant.now().toEpochMilli() ;
Run Code Online (Sandbox Code Playgroud)

有没有办法可以解析这些值的时钟时间?

是的,您可以将自1970-01-01T00:00Z纪元以来的毫秒数转换为a Instant.

Instant instant = Instant.ofEpochMilli( millisSinceEpoch ) ;
Run Code Online (Sandbox Code Playgroud)

System.nanoTime()

至于System.nanoTime(),它用于跟踪已用时间,例如对代码的性能进行基准测试.呼叫System.nanoTime()不会告诉你当前的日期,时间什么.

此值是自某些未记录的原点时间点以来的纳秒数.在实践中,我已经看到该数字似乎跟踪自JVM启动以来的时间,但是这种行为没有记录,因此您不应该依赖它.

LocalDateTime不是一时

我的问题是我需要使用Java和Javascript进行日志记录,并且需要在两者之间都有一致的微秒字段.

首先,对于日志记录,您应该使用LocalDateTime类.该类故意缺乏任何时区概念或从UTC偏移.这样,LocalDateTime不是代表了一下,是不是在时间轴上的一个点.A LocalDateTime是关于在大约26-27小时范围内的潜在时刻的想法.使用LocalDateTime仅抵消区/未知(不是一个好的情况),或者如果这代表类似"圣诞节开始于Decemeber 25,2018的第一时刻",在圣诞节开始于为全球不同地区的不同时刻,开始首先在远东(太平洋),并在午夜连续午夜向西移动.

对于日志记录,您应该使用UTC.在Java中,这将是Instant类,始终按UTC定义.打电话吧Instant.now().

序列化为日志等文本时,请始终使用标准ISO 8601格式.在解析/生成字符串时,java.time类默认使用这些标准格式.您在本答案中看到了上述示例.

查看另一个问题,Instant和LocalDateTime有什么区别?.

ISO 8601

在ISO 8601中,秒的小数部分可以具有任意数量的数字.所以你真的不应该关心记录的事件是以毫秒,微秒还是纳秒记录的.

Instant instant = Instant.parse( "2018-03-09T21:03:33.123456789Z" ) ;
Instant instant = Instant.parse( "2018-03-09T21:03:33.123456Z" ) ;
Instant instant = Instant.parse( "2018-03-09T21:03:33.123Z" ) ;
Run Code Online (Sandbox Code Playgroud)

截短

如果你真的相信你需要统一的分辨率,你可以截断一个Instant.

Instant instant = Instant.now().truncatedTo( ChronoUnit.MILLIS ) ; // Strip away any microseconds or nanoseconds.
Run Code Online (Sandbox Code Playgroud)

不要担心解决方案

我的问题是我需要使用Java和Javascript进行日志记录,并且需要在两者之间都有一致的微秒字段.

首先,我怀疑你真的需要关心这一点.如果您使用标准的ISO 8601格式和InstantJava类,您可以使用毫秒,微米或纳米成功地序列化和重新水合.

即使分数秒的分辨率变化,ISO 8601格式的字符串也可以按时间顺序按字母顺序排列.

其次,如果您因某种原因试图将实际时刻跟踪到微秒,您可能会感到失望.截至2018年,传统计算机时钟在微秒范围内不可靠.


关于java.time

java.time框架是建立在Java 8和更高版本.这些类取代麻烦的老传统日期时间类,如java.util.Date,Calendar,和SimpleDateFormat.

现在处于维护模式Joda-Time项目建议迁移到java.time类.

要了解更多信息,请参阅Oracle教程.并搜索Stack Overflow以获取许多示例和解释.规范是JSR 310.

您可以直接与数据库交换java.time对象.使用符合JDBC 4.2或更高版本的JDBC驱动程序.不需要字符串,不需要课程.java.sql.*

从哪里获取java.time类?

ThreeTen-额外项目与其他类扩展java.time.该项目是未来可能添加到java.time的试验场.您可以在此比如找到一些有用的类Interval,YearWeek,YearQuarter,和更多.

  • 多么好的答案啊! (6认同)