现在有没有一种新的方法可以在Java中以微秒精度获取当前时间?

15

我查看了下面的页面,2009年Java中没有获取微秒级准确时间的方法。


java中的微秒级当前时间

其中最好的方法是System.currentTimeMillis(),它可以提供毫秒级准确度的当前时间,而System.nanoTime()可以提供纳秒级准确度的当前时间戳,但是该时间戳不能用于高精度转换为当前时间。

请问在6年后的Java中是否有任何新的更新?谢谢。

编辑1:System.nanoTime() 对于估计持续时间很有用,但无法提供当前时间。

编辑2:在Java 8中有解决方案,但在Java 7中是否有其他方法呢?谢谢!


纳秒比微秒更精确。此外,您的帖子中提供了一个解决方案。 - Flown
可能是System.currentTimeMillis vs System.nanoTime的重复问题。 - Andrei Sfat
1
当然,计时逻辑的精度完全取决于操作系统和硬件,实际上并不是Java生成这些数字。 - Gimby
@BasilBourque 谢谢,我已经删除了我的评论。我很久以前写下那条评论时并没有完全理解 OP 是在寻求准确性。 - Mitesh Pathak
3个回答

15

简短精炼

Instant.now()

2018-03-09T21:03:33.831515Z

使用 Java 9 及其之后的版本,你可以以微秒分辨率捕捉当前时刻。

上方的示例是适用于macOS Sierra 的 Oracle Java 9.0.4。请注意6位小数,即微秒。


java.time

Java 8及其后续版本内置了java.time框架,其中的类可以表示日期时间值,分辨率为纳秒,即小数点后9位。

Java 9

Java 9的OpenJDK实现具有Clock的全新实现,可达到纳秒级分辨率。实际值取决于任何特定计算机的底层硬件时钟限制。

更多信息请参见问题为什么新的Java 8日期时间API没有纳秒精度?

避免使用旧的日期时间类。早期版本的Java中捆绑的java.util.Date/.Calendar等类仅具有毫秒级分辨率。Joda-Time也是如此。这两个类都被java.time类所取代。

Java 8

Java 8使用Clock接口仅具有毫秒分辨率(3位小数秒)。因此,虽然java.time类能够携带纳秒,但无法捕获当前时间的纳秒。

本地代码

也许您可以编写或找到一个Clock实现,它调用主机操作系统中的本地库以获取更准确的时间。

数据库

如果您已经在使用数据库,则可以向其请求时间。从JDBC 4.2及更高版本开始,您可以直接与数据库交换java.time对象。

Instant instant = myPreparedStatement.getObject( … , Instant.class ) ;

在JDBC 4.2之前,您可以通过麻烦的传统java.sql.Timestamp 遍历,它具有纳秒分辨率。例如,Postgres提供微秒 分辨率(假设主机计算机时钟支持该分辨率),即6位小数秒。您可以使用添加到旧类中的新方法将java.sql.Timestamp转换为InstantZonedDateTime

enter image description here


关于java.time

java.time框架内置于Java 8及更高版本中。这些类取代了老旧的传统日期时间类,如{{link3:java.util.Date}}、{{link4:Calendar}}和{{link5:SimpleDateFormat}}。

想要了解更多,请参阅Oracle教程。并在Stack Overflow上搜索许多示例和解释。规范是JSR 310

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

您可以直接使用java.time对象与数据库进行交换。使用符合JDBC 4.2或更高版本的JDBC驱动程序。无需字符串,无需java.sql.*类。Hibernate 5和JPA 2.2支持java.time

如何获取java.time类?

ThreeTen-Extra项目通过添加类来扩展java.time。这个项目是可能未来增加的java.time类的试验场所。你可以在这里找到一些有用的类,例如Interval, YearWeek, YearQuarter更多


6

如果您需要相关的技术支持,Java 8 java.time 包可以为您提供帮助。

尝试使用以下方法:

LocalDateTime.now(); // The current timestamp accurate to nanoseconds
LocalDateTime.now().getLong(ChronoField.MICRO_OF_SECOND); // the microseconds part
LocalDateTime.now().getLong(ChronoField.NANO_OF_SECOND); // even finer
LocalDateTime.now().getDayOfMonth(); // main parts of the date have their own methods
LocalDateTime.now().getMonth(); // etc  

如果只需要将纳秒作为字符串获取,可以在格式中使用nnnnnnnnn

LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.nnnnnnnnn"));  

将其解析为日期对象,如果需要更多格式化,请使用“SimpleDateFormatter”。 - Jude Niroshan
@JudeNiroshan FYI,诸如java.util.Datejava.util.Calendarjava.text.SimpleTextFormat等麻烦的旧日期时间类现在已经成为遗留系统,被Java.time类所取代。请参阅Oracle教程 - Basil Bourque

2

从新的Java 8 java.time中获取当前时间的另一种方法是使用Clock类。

Clock.systemUTC().millis()

提供当前时间的毫秒数(自纪元以来的长整型毫秒数)或

Clock.systemUTC().instant()

根据官方Oracle Java教程,此方法返回一个Instant类的实例,“该实例代表了时间轴上的一纳秒起点”。该教程展示了如何使用这个新类,如何转换为本地时间、UTC时间或带时区的日期时间等。


1
这些中哪一个可以给你微秒级别的时间? - Andy Turner

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接