API Duration был немного , что меня удивило, потому что вы должны получить часть длительности секунд с Duration.getField (Field) . Этот метод возвращает Number
, то есть либо BigInteger
(для дней, часов, минут и т. Д. c), либо 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
Это работает, но слишком сложно. Должен быть более простой способ сделать это.
@ ответ hasnae решение выглядит намного лучше, если вы используете Java 1.8. Интересно, каким был намеренный для разработчика API способ получить точность наносекунды, поскольку java.time.Duration
был введен на несколько лет позже, чем javax.xml.datatype.Duration
.