javax.xml.datatype.Duration to nanoseconds



我有一个包含毫秒分数的javax.xml.datatype.Duration,例如持续时间为 1.5 毫秒(1500 微秒(:

Duration duration = DatatypeFactory.newInstance().newDuration("PT0.0015S");

我需要以纳秒为单位获取此值,但Duration提供的最小时间单位似乎是getTimeInMillis,它返回一个long并削减小于一毫秒的任何内容。

如何获取以纳秒为单位的持续时间?

您可以将持续时间解析为java.time.Duration。然后调用toNanos()方法。

Duration duration = DatatypeFactory.newInstance().newDuration("PT0.0015S");
java.time.Duration.parse(duration.toString()).toNanos();

DurationAPI 在这里让我有点惊讶,因为您必须使用 Duration.getField(Field( 获取持续时间的数部分。该方法返回一个Number,它可以是BigInteger(天、小时、分钟等(或BigDecimal(仅秒(。

因此,要获得几分之一秒,您可以使用getField(DatatypeConstants.SECONDS)然后转换值:

Duration duration = DatatypeFactory.newInstance().newDuration("PT0.0015S");
BigDecimal seconds = (BigDecimal) duration.getField(DatatypeConstants.SECONDS);
// Note that `getField` will return `null` if the field is not defined.
if(seconds != null) {
System.out.println(seconds + "s");                    // 0.0015s
System.out.println(seconds.movePointRight(9) + "ns"); // 1500000ns
}

但这些并不是持续时间的总秒数。这只是秒字段的值,其他字段将被忽略。对于像P1M0.0015(1 分 1.5 毫秒(这样的持续时间,这将忽略分钟,只返回 1.5 毫秒。

将持续时间的所有其他字段转换为秒并将它们相加将起作用。或者使用getTimeInMillis,返回持续时间的总毫秒数:

Duration duration = DatatypeFactory.newInstance().newDuration("PT1M0.0015S");
BigDecimal seconds = (BigDecimal) duration.getField(DatatypeConstants.SECONDS);
// only keep the fractional part
BigDecimal fractionalSeconds = seconds.remainder(BigDecimal.ONE);
long totalMillis = duration.getTimeInMillis(new Date(0));
// convert total millis to whole seconds (removes fractional part)
BigDecimal totalIntegerSeconds = 
new BigDecimal(totalMillis).movePointLeft(3).setScale(0, RoundingMode.FLOOR);
// add both to get total seconds 
BigDecimal totalSeconds = totalIntegerSeconds.add(fractionalSeconds);
System.out.println(totalSeconds + "s");                     // 60.0015s
System.out.println(totalSeconds.movePointRight(9) + "ns");  // 60001500000ns

这似乎有效,但太复杂了。必须有一种更简单的方法可以做到这一点。

如果您使用的是Java 1.8,@hasnae的答案解决方案看起来要好得多。我想知道 API 设计者获得纳秒级精度的预期方法是什么,因为java.time.Durationjavax.xml.datatype.Duration晚了几年。

最新更新