当前位置: 首页 > 知识库问答 >
问题:

Java 8 LocalDateTime.now()只提供毫秒级的精度

宰父智敏
2023-03-14

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

因为javascript方法process.hrtime()返回一个精确值,所以可以在我的计算机上获得纳秒(因此可以从中获得微秒)。

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

编辑:

所以我意识到JavaScript的process.hrtime就像Java的system.nanotime()一样,实际上与挂钟并不相关,因为这是两种语言不同的任意值。

新问题:有没有方法可以从这些值解析时钟时间?例如,如果我获得System.CurrentTimeMillis()System.nanoTime(),并将其与另一组这些值进行比较,我是否可以获得第二组值的实际时间?

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

共有1个答案

于意智
2023-03-14

在Java 8中有可能获得微秒吗?

不。请使用Java9或更高版本。

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

这是指Java8/9的Oracle&OpenJDK实现。其他的可能会有所不同。

Instant.now().toString()

2018-03-09T21:03:33.831Z

如果我获得System.CurrentTimeMillis()和System.nanoTime()

不再需要使用System.CurrentTimeMillis()。使用java.time.instantUTC片刻,分辨率可以达到纳秒级。

long millisSinceEpoch = instant.now().toEpochMilli() ;

是的,您可以将1970-01-01T00:00Z以来的毫秒计数转换为即时

Instant instant = Instant.ofEpochMilli( millisSinceEpoch ) ;

对于system.nanotime(),它用于跟踪经过的时间,例如对代码的性能进行基准测试。调用System.nanoTime()不会告诉您关于当前日期-时间的任何信息。

此值是从某个未记录的起始时间点开始的纳秒计数。在实践中,我已经看到这个数字跟踪JVM启动以来的时间,但是这个行为没有文档化,所以您不应该依赖它。

首先,对于日志记录,您不应该使用localdatetime类。该类故意缺少任何时区或与UTC偏移量的概念。因此,localdatetime并不表示时刻,也不是时间线上的点。localdatetime是一个关于26-27小时范围内的潜在时刻的概念。仅当区域/偏移量未知(不是好的情况),或者表示“圣诞节开始于2018年12月25日的第一个时刻”时,才使用localdatetime,其中圣诞节在全球不同地区的不同时刻开始,首先从远东(太平洋)开始,然后在连续的午夜之后向西移动。

对于日志记录,您应该使用UTC。在Java中,这将是instant类,根据定义,它总是使用UTC。只需调用instant.now()

当序列化为文本(例如用于日志记录)时,始终使用标准的ISO 8601格式。在解析/生成字符串时,java.time类默认使用这些标准格式。你在上面的答案中看到了一些例子。

参见另一个问题,Instant和LocalDateTime之间有什么区别?。

在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" ) ;

如果您真的认为您需要统一的分辨率,您可以截断一个即时

Instant instant = Instant.now().truncatedTo( ChronoUnit.MILLIS ) ; // Strip away any microseconds or nanoseconds.

其次,如果出于某种原因,你正试图跟踪实际时刻到微秒,你很可能会失望。截至2018年,常规计算机时钟在微秒级范围内并不可靠。

Java.time框架内置在Java8和更高版本中。这些类取代了麻烦的旧的遗留日期-时间类,如java.util.dateCalendar、&SimpleDateFormat

要了解更多信息,请参阅Oracle教程。并搜索堆栈溢出以获得许多示例和解释。规范是JSR310。

    null
    null
  • Android(26+)的更高版本捆绑了java.time类的实现。
  • 对于早期的Android(<26),API解聚的过程带来了Android中最初没有内置的java.time功能的子集。
    • 如果desugaring不能提供您需要的内容,那么ThreeTenABP项目将ThreeTen-Backport(上面提到)适配到Android。查看如何使用ThreeTenabp…。

 类似资料:
  • 我现在用SDL2编程。所有这些都可以正常工作,但我对方法有一个问题。通常,它应该以毫秒为单位返回应用程序的总时间,但它总是在大部分时间返回值0,有时返回值1。 我用标志初始化SDL。 以下代码的问题是循环太快,因此增量时间小于1 ms。是否有方法实现更高的精度?

  • 我在代码中使用倒计时。问题是,倒计时不准确。onTick方法并不总是每秒执行一次,它可能需要几毫秒的时间。当试图基于millisUntilFinished执行某项任务时,这会成为一个问题。当我的20秒计时器超过10秒时,我正在尝试登录: 以下是相关代码: 这里出现了一个问题,因为countDownTimer可能永远不会有millisUntilFinished==10000,它可能等于1001,因此

  • Spring启动版本“2.3.4.release” Java 11 org.springframework.Boot:spring-boot-starter-jdbc org.springframework.Boot:spring-boot-starter-data-jpa spring-data-jpa-2.3.4.release 运行时(mysql:mysql-connector-java)

  • sleep(500)将挂起当前线程至少500毫秒,我知道它可能会比500多一点,但绝不会少于这个时间。现在,1毫秒=1000000纳秒,我想暂停当前线程500毫秒,即=500*1000000纳秒,但当我运行以下代码时,它有时睡眠时间少于指定的纳秒值。这是为什么呢?以及如何至少睡500*1000000纳秒。 有时输出是

  • 问题内容: 因此,我刚刚发现MySQL中最令人沮丧的错误。 显然,该字段及其支持功能不支持比秒更高的精度! 所以我正在使用PHP和Doctrine,我真的需要那些微秒(我正在使用属性)。 我发现我可以使用一个字段来存储值。但是学说会增加毫秒吗?我认为它只是将NOW()分配给该字段。我还担心通过代码散布的日期操作功能(在SQL中)会中断。 我还看到了有关编译UDF扩展的内容。这是不可接受的,因为我或

  • 问题内容: 我想将毫秒转换为秒(例如,将1500ms转换为1.5s,或将500ms转换为0.5s)。 并不是最好的方法:我正在寻找一种从除法运算中获取余数的方法,因此我可以简单地添加余数。 问题答案: 当然,您只需要: 无需分别手动执行这两个部分- 您只需要浮点运算即可(使用字面量)即可。(我假设您的值是某种形式的整数。) 请注意,和一样,您可能无法准确表示结果。如果您想 精确地 将100ms表示