Я перехожу к проекту из Joda-Time в библиотеки времени java8, и я столкнулся с проблемой. Я не смог найти форматировщик для Duration. Я хотел бы иметь собственный формат String, например, HHH + MM, где длительность 75 часов и 15 минут будет отформатировать как "75 + 15". Это было легко сделать с Joda-Time путем преобразования в период и использования PeriodFormatter, но я не смог найти этот тип класса в Java8. Я что-то пропустил?
Форматирование продолжительности в Java 8/jsr310
Ответ 1
В jsr-310 нет периода/длительности-форматирования, отличного от JodaTime. Не каждая функция JodaTime была перенесена на JSR-310 (например, также не PeriodType). А в обратном JSR-310 есть некоторые функции, недоступные в JodaTime (например, локализованные числа в будние дни или подход с шаблоном стратегии с регуляторами).
Может случиться так, что Java 9 представит какое-то встроенное форматирование периода (прочитайте что-нибудь об этом от S. Colebourne).
Заключение: JSR-310 и JodaTime не полностью совместимы друг с другом, поэтому может потребоваться много работы. Я бы не стал так стремиться к миграции как можно скорее. Вам нужны специальные функции JSR-310, которые не предлагаются JodaTime?
Дополнительное примечание: вы также должны знать о том, что период joda (который включает все единицы от нескольких лет до нескольких секунд) не полностью совместим с периодом jsr310 (только годы, месяцы, дни) или jsr310-duration (только часы, минуты, секунды и доли секунды).
Ответ 2
Java 9 и более поздние Duration::to…Part
: Duration::to…Part
методы Duration::to…Part
В Java 9 класс Duration
получил новые методы to…Part
для возврата различных частей дней, часов, минут, секунд, миллисекунд/наносекунд. Смотрите этот предварительный выпуск исходного кода OpenJDK.
Учитывая продолжительность 49H30M20.123S...
-
toNanosPart()
= 123000000 -
toMillisPart()
= 123 -
toSecondsPart()
= 20 -
toMinutesPart()
= 30 -
toHoursPart()
= 1 -
toDaysPart()
= 2
Помните, что "дни" здесь означают куски по 24 часа, игнорируя даты в календаре. Если вам небезразличны даты, используйте вместо этого класс Period
.
Я не знаю, были ли добавлены какие-либо дополнительные функции форматирования. Но, по крайней мере, вы сможете более удобно генерировать свои собственные строки из чисел, полученных с помощью этих новых методов получения.
Java 8
Как ни странно, в первый выпуск java.time в Java 8 не были включены удобные методы получения этих значений. Это один из немногих недостатков в отличном дизайне фреймворка java.time.
См. Соответствующий вопрос: Почему я не могу получить продолжительность в минутах или часах в java.time? ,
Ответ 3
Нет встроенного метода, но вы можете получить доступ к количеству часов/минут без необходимости их вычисления вручную. Ваш конкретный формат может выглядеть так:
Duration d = Duration.of(75, HOURS).plusMinutes(15);
long hours = d.toHours(); //75
long minutes = d.minusHours(hours).toMinutes(); //15
String HH_PLUS_MM = hours + "+" + minutes; //75+15
System.out.println(HH_PLUS_MM);
Если продолжительность будет меньше 24 часов, вы также можете использовать этот трюк:
String hhPlusMm = LocalTime.MIDNIGHT.plus(d).format(DateTimeFormatter.ofPattern("HH+mm"));
Ответ 4
Вы можете использовать DurationFormatUtils из commons-lang3-time (в течение нескольких минут вы должны использовать "mm", поскольку формат такой же, как в SimpleDateFormat
): DurationFormatUtils.formatDuration(interval.toMillis(), "HHH+mm")
К сожалению, я не нашел способа исключить пустые части, так как в моем случае дни или часы могли быть равны 0, поэтому мне все равно пришлось свернуть свои собственные.
Обновление: я открыл проблему для этого на Apache commons.lang.time.DurationFormatUtils JIRA.
Ответ 5
Я знаю, что это старый вопрос, но я недавно столкнулся с тем же. Там действительно должно быть лучшее решение, чем это, но это сработало для меня:
public static String millisToElapsedTime(long millis){
DateFormat fmt = new SimpleDateFormat(":mm:ss.SSS");
fmt.setTimeZone(TimeZone.getTimeZone("UTC"));
return (millis/3600000/*hours*/)+fmt.format(new Date(millis));
}
Затем вы можете добавить это:
public static String durationToElapsedTime(Duration d){
return millisToElapsedTime(d.toMillis());
}