8

First of all I'm new to java.time package.

I'm writing a webapp that need to work with specific times of the day and with several durations of events.

So I wrote my code using LocalTime and Duration classes of java.time package.

When I need to render their value in JSP it is very simple for LocalTime object (because .toString() returns a human readable vale), so I can just write ${startTime} and everything goes in the right way (e.g. it is rendered as 9:00). The same approach doesn't work for Duration, because its representation is something like PT20M (in this case for 20 minutes).

Does it exist an elegant way to perform a human-readable conversion in JSP directly by EL?

Yes, I know I can convert the object in a string in my classes (before JSP), but I'm searching for the suggested approach (that I'm not able to find)... another point is that I not see an official "convert()" (or whatever else) method in Duration object... so I'm thinking I'm using the wrong object to map a duration of time (to add or subtract on LocalTimes).

Thank you.

Pierpaolo Cira
  • 1,457
  • 17
  • 23
  • 2
    Do you need a formatted textual duration only in English or also in any other language (like "1 Stunde und 20 Minuten" in German)? If other languages are important then I recommend to use an extra 3rd-party-library. Java-8 does not contain any built-in duration formatting, see also the correct answer of @Erlandsson which is sufficient if you only need a numerical form. – Meno Hochschild Jun 28 '15 at 01:38
  • In truth I just need a 20 for 20 minutes, or 1:20 for 1 hour and 20 minutes... nothing to do with localization, just a human readable form... – Pierpaolo Cira Jun 28 '15 at 16:44

2 Answers2

7

Unfortunately there exists no elegant builtin way to format a Duration in Java 8. The best i have found is to use the method bobince describes in this answer:

    Duration duration = Duration.ofHours(1).plusMinutes(20);
    long s = duration.getSeconds();
    System.out.println(String.format("%d:%02d:%02d", s/3600, (s%3600)/60, (s%60)));

Which prints:

1:20:00

The code will have to be tuned if you need longer durations.

I'm not sure what you mean that you are missing a convert method, but Duration is well suited for adding/subtracting on LocalTime. The methods LocalTime.plus() and LocalTime.minus() accepts Duration as argument.

Community
  • 1
  • 1
K Erlandsson
  • 13,408
  • 6
  • 51
  • 67
  • Thank you... I'm exactly using duration only to represent the duration of an event (so, if the LocalTime is 9:00 an there is a duration of 30 mins, I can use what you wrote to get another LocalTime as a summation: 9:30). Speaking of something like a "convert()" method, I'm just referring to the absence of a method to convert the Duration object in a String representation (that is again the topic of the question... it is only a repetition). By the way... it is very strange to don't have a taglib or someting else to do what I need for Duration, but LocalTime perform this simply by its toString() – Pierpaolo Cira Jun 28 '15 at 16:50
  • At the end I decided to create another get method in my bean, that will be used on demand by my EL code: I wrote `${item.myDurationStr}` instead of `${item.myDuration}`, and it will "convert" the format, with a code like `public String getMyDurationStr() {` `long sec = myDuration.getSeconds();` `return String.format("%02d:%02d", sec/3600, (sec%3600)/60); // I don't need for seconds` `}` – Pierpaolo Cira Jun 28 '15 at 20:45
4

If you're interested in words, apache commons will do the trick:

 DurationFormatUtils.formatDurationWords(System.currentTimeMillis() - start, true, false))
 2 days 1 hour 5 minutes 20 seconds

https://commons.apache.org/proper/commons-lang/apidocs/org/apache/commons/lang3/time/DurationFormatUtils.html#formatDurationWords-long-boolean-boolean-

Charlie
  • 8,530
  • 2
  • 55
  • 53