Подтвердить что ты не робот

Форматирование продолжительности в Java 8/jsr310

Я перехожу к проекту из Joda-Time в библиотеки времени java8, и я столкнулся с проблемой. Я не смог найти форматировщик для Duration. Я хотел бы иметь собственный формат String, например, HHH + MM, где длительность 75 часов и 15 минут будет отформатировать как "75 + 15". Это было легко сделать с Joda-Time путем преобразования в период и использования PeriodFormatter, но я не смог найти этот тип класса в Java8. Я что-то пропустил?

4b9b3361

Ответ 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());
}