【问题标题】:What is the jconsole time format?jconsole 时间格式是什么?
【发布时间】:2019-12-20 11:06:39
【问题描述】:

我最近使用 jconsole 监控了我的 java 程序。我将 CPU 使用率数据保存为 csv 文件。这就是我所拥有的:

Time,CPU Usage
43690.008014,1,8
43690.008060,0,1
43690.008106,0,1
43690.008153,0,1
43690.008199,0,1
43690.008245,0,1

CPU Usage 栏很清楚,但我不能对Time 栏说同样的话。 43690.008014 是什么?如何将其解析为Date?我这辈子没见过这样的事。

【问题讨论】:

  • 您的答案在Using JConsole 文档中吗?那里有很多信息。
  • 时间格式基于1/1/1900后的天数(基于此link)。
  • 但如果他们真的基于 excel,那么它似乎也受到time leap bug 的影响,因为它是一天的休息日。

标签: java time duration jconsole


【解决方案1】:

CSV 文件中记录的持续时间是自1899-12-311 以来的天数。为了获取当前日期,您可以将此持续时间添加到LocalDate.of(1899, 12, 30).atStartOfDay().atOffset(ZoneOffset.UTC)。我建议您使用java.time.Duration,它以ISO-8601 standards 为蓝本,并作为JSR-310 implementation 的一部分与Java-8 一起引入。函数Duration#ofNanos 为您提供一个Duration,表示指定的纳秒数。尽管已经有一个函数Duration#ofDays,我还是建议您使用此函数的原因是这些函数将long 值作为参数,并且如果您在日志文件中转换持续时间(例如@ 987654338@) 到long,它的小数部分将会丢失,给你一个不正确的结果。

因此,将这些天数转换为纳秒,从生成的纳秒中获取 Duration,并将其添加到 LocalDate.of(1899, 12, 30).atStartOfDay().atOffset(ZoneOffset.UTC) 以在 UTC 中获取当前日期和时间。

演示:

import java.time.Duration;
import java.time.LocalDate;
import java.time.OffsetDateTime;
import java.time.ZoneOffset;

public class Main {
    public static void main(String[] args) {
        OffsetDateTime startDateTime = LocalDate.of(1899, 12, 30).atStartOfDay().atOffset(ZoneOffset.UTC);
        OffsetDateTime current = startDateTime
                .plus(Duration.ofNanos((long) (43690.008014 * 24 * 60 * 60 * 1000_000_000)));
        System.out.println(current);
    }
}

输出:

2019-08-13T00:11:32.409600512Z

Trail: Date Time 了解现代日期时间 API。


1 Why is 1899-12-30 the zero date in Access / SQL Server instead of 12/31?

【讨论】:

    【解决方案2】:

    时间格式为daysSinceEpoch.fractionOfCurrentDay

    daysSinceEpoch 开始于 1899-12-30 而不是 1900-01-01

    fractionOfCurrentDay 是当天的百万分之一,范围从零到 999999 (23:59:59)

    您可以使用以下函数转换为LocalDateTime:

       public static LocalDateTime convert( final String jconsoleDateFormat )
       {
          String[] split = jconsoleDateFormat.split( "\\." );
          long daysSinceEpoch = Long.parseLong( split[0] );
          long dayFraction = Long.parseLong( split[1] );
    
          LocalDateTime epochDate = LocalDateTime.of( 1899,12,30, 0,0 );
          LocalDateTime currentDate = epochDate.plusDays( daysSinceEpoch );
    
          long secondsADay = 24 * 60 * 60L; // 86_400
          long secondsSinceDayStarted = secondsADay * dayFraction / 1_000_000;
          return currentDate.plusSeconds( secondsSinceDayStarted );
       }
    
       public static void main( String[] args )
       {
          System.out.println( convert( "43690.008014" ) ); // 2019-08-13T00:11:32
       }
    

    【讨论】:

      猜你喜欢
      • 2020-09-14
      • 2017-04-28
      • 2018-11-27
      • 1970-01-01
      • 2011-10-16
      • 1970-01-01
      • 2013-12-25
      • 2013-05-11
      相关资源
      最近更新 更多