Как я могу" красиво распечатать " продолжительность в Java?
кто-нибудь знает библиотеку Java, которая может довольно печатать число в миллисекундах так же, как и C#?
например, 123456 МС как долго будет печататься как 4d1h3m5s.
10 ответов:
Джода Времени есть хороший способ сделать это с помощью PeriodFormatterBuilder.
Быстрая Победа:
PeriodFormat.getDefault().print(duration.toPeriod());
например
//import org.joda.time.format.PeriodFormatter; //import org.joda.time.format.PeriodFormatterBuilder; //import org.joda.time.Duration; Duration duration = new Duration(123456); // in milliseconds PeriodFormatter formatter = new PeriodFormatterBuilder() .appendDays() .appendSuffix("d") .appendHours() .appendSuffix("h") .appendMinutes() .appendSuffix("m") .appendSeconds() .appendSuffix("s") .toFormatter(); String formatted = formatter.print(duration.toPeriod()); System.out.println(formatted);
Я создал простое решение, используя Java 8 по
Duration.toString()
и немного регулярных выражений:public static String humanReadableFormat(Duration duration) { return duration.toString() .substring(2) .replaceAll("(\d[HMS])(?!$)", " ") .toLowerCase(); }
результат будет выглядеть так:
- 5h - 7h 15m - 6h 50m 15s - 2h 5s - 0.1s
если вы не хотите пробелов между ними, просто удалите
replaceAll
.
JodaTime есть
Period
класс, который может представлять такие величины и может быть отображен (черезIsoPeriodFormat
) в в формате iso8601, например,PT4D1H3M5S
, например,Period period = new Period(millis); String formatted = ISOPeriodFormat.standard().print(period);
если этот формат не тот, который вы хотите, затем
PeriodFormatterBuilder
позволяет собирать произвольные макеты, в том числе C#-style4d1h3m5s
.
С Java 8, вы также можете использовать
toString()
методjava.time.Duration
чтобы отформатировать его без внешних библиотек с помощью ISO 8601 секунд на основе представления такие как PT8H6M12.345S.
Apache commons-lang предоставляет полезный класс, чтобы сделать это, а также DurationFormatUtils
например,
DurationFormatUtils.formatDurationHMS( 15362 * 1000 ) )
=> 4:16:02.000 (H:m:s.millis)DurationFormatUtils.formatDurationISO( 15362 * 1000 ) )
=> P0Y0M0DT4H16M2.000С, ср. В формате iso8601
вот как вы можете сделать это с помощью чистого кода JDK:
import javax.xml.datatype.DatatypeFactory; import javax.xml.datatype.Duration; long diffTime = 215081000L; Duration duration = DatatypeFactory.newInstance().newDuration(diffTime); System.out.printf("%02d:%02d:%02d", duration.getDays() * 24 + duration.getHours(), duration.getMinutes(), duration.getSeconds());
Я понимаю, что это может не соответствовать вашему случаю использования точно, но PrettyTime может быть полезным здесь.
PrettyTime p = new PrettyTime(); System.out.println(p.format(new Date())); //prints: “right now” System.out.println(p.format(new Date(1000*60*10))); //prints: “10 minutes from now”
альтернативой подходу строителя Джоды-времени было бы решение на основе шаблонов. Это предлагает Моя библиотека Time4J. Пример использования класса длительность.Форматер (добавлено несколько пробелов для большей читаемости-удаление пробелов даст желаемый стиль C#):
IsoUnit unit = ClockUnit.MILLIS; Duration<IsoUnit> dur = Duration.of(123456, unit).with(Duration.STD_PERIOD); String s = Duration.Formatter.ofPattern("D'd' h'h' m'm' s.fff's'").format(dur); System.out.println(s); // output: 0d 0h 2m 3.456s
другой способ-это использование класса
net.time4j.PrettyTime
(что также хорошо для локализованного вывода и печати относительного времени):s = PrettyTime.of(Locale.ENGLISH).print(dur, TextWidth.NARROW); System.out.println(s); // output: 2m 3s 456ms
Java 9
Duration d1 = Duration.ofDays(0); d1 = d1.plusHours(47); d1 = d1.plusMinutes(124); d1 = d1.plusSeconds(124); System.out.println(String.format("%s d %sh %sm %ss", d1.toDaysPart(), d1.toHoursPart(), d1.toMinutesPart(), d1.toSecondsPart()));
2 d 1h 6m 4s
A Java 8 версия, основанная на ответ пользователя 678573:
private static String humanReadableFormat(Duration duration) { return String.format("%s days and %sh %sm %ss", duration.toDays(), duration.toHours() - TimeUnit.DAYS.toHours(duration.toDays()), duration.toMinutes() - TimeUnit.HOURS.toMinutes(duration.toHours()), duration.getSeconds() - TimeUnit.MINUTES.toSeconds(duration.toMinutes())); }
... поскольку в Java 8 нет PeriodFormatter и нет таких методов, как getHours, getMinutes,...
Я был бы рад увидеть лучшую версию для Java 8.