什么是 jconsole 时间格式?



我最近用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?我一生中从未见过这样的事情。

CSV 文件中记录的持续时间是自1899-12-311以来的天数。为了获取当前日期,您可以将此持续时间添加到LocalDate.of(1899, 12, 30).atStartOfDay().atOffset(ZoneOffset.UTC).我建议您使用以 ISO-8601 标准为模型的java.time.Duration,并在 JSR-310 实现中随Java-8一起引入。该函数Duration#ofNanos为您提供一个表示指定纳秒数的Duration。尽管已经有一个函数,但我建议您使用此函数的原因是,Duration#ofDays这些函数将long值作为参数,并且如果您在日志文件中强制转换持续时间(例如43690.008014(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

跟踪:日期时间中了解现代日期时间 API。

  • 出于任何原因,如果你必须坚持使用 Java 6 或 Java 7,你可以使用ThreeTen-Backport,它将大部分java.time功能向后移植到 Java 6 和 7。
  • 如果您正在为 Android 项目工作,并且您的 Android API 级别仍然不符合 Java-8,请查看通过脱糖提供的 Java 8+ API 和如何在 Android Project 中使用 ThreeTenABP。

1 为什么 Access/SQL Server 中的 1899-12-30 是零日期,而不是 12/31?

时间格式为daysSinceEpoch.fractionOfCurrentDay

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

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

您可以使用以下函数转换为本地日期时间:

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
}

最新更新