I want to format a java.time.LocalTime
, but the format can vary according to its value:
HH:mm
HH:mm:ss
Of course I could do it like this:
if (t.getHour() == 12 || t.getHour() == 0) {
// use "HH:mm" formatter
} else {
// use "HH:mm:ss" formatter
}
But for that I need to create 2 different formatters.
I want to use just one formatter that can be reused many times:
DateTimeFormatter fmt = // create this "conditional" formatter
fmt.format(LocalTime.of(14, 0))); // 14:00:00
fmt.format(LocalTime.of(12, 0))); // 12:00
I'm trying to do it with a DateTimeFormatterBuilder
:
DateTimeFormatter fmt = new DateTimeFormatterBuilder()
.appendPattern("HH:mm")
// how to append seconds (and the ":" before it) only if hour of day is not (12 or 0)?
.appendLiteral(":").appendValue(ChronoField.SECOND_OF_MINUTE, 2)
.toFormatter();
I tried with DateTimeFormatterBuilder.optionalStart()
and optionalEnd()
methods, and also with appendOptional()
, but these methods only check if the field being appended is present.
They don't have an optional behaviour based on another field's value.
How can I do it with just one formatter (if possible)?
See DateTimeFormatterBuilder
and the method appendText(TemporalField,Map). It allows you to convert each number to a specific piece of text. However, since you want to base the seconds on the hour, you'll have to setup a map of 86400 entries, one for every second in the day. But it will then work as a single formatter.
Map<Long, String> map = new HashMap<>();
map.put(0L, "00:00");
map.put(1L, "00:00"); // would normally be 00:00:01
map.put(2L, "00:00"); // would normally be 00:00:02
map.put(60L, "00:01");
// and so on
map.put(3600L, "01:00:00");
map.put(3601L, "01:00:01");
// and so on to 86399
DateTimeFormatter fmt = new DateTimeFormatterBuilder()
.appendText(ChronoField.SECOND_OF_DAY, map)
.toFormatter();
A map of 86400 entries is of course silly, but its the best you can do with the API as is. Really, there needs to be an appendText(TemporalField, LongFunction<String>)
method added to DateTimeFormatterBuilder
(which would result in a formatter that could not be used for parsing).