I am trying to understand how to build a custom DateTimeFormatter
for my application. I basically need to handle time that are written like this "HHMMSS.FFFFFF".
I was able to get 99% of it using:
import static java.time.temporal.ChronoField.HOUR_OF_DAY;
import static java.time.temporal.ChronoField.MICRO_OF_SECOND;
import static java.time.temporal.ChronoField.MINUTE_OF_HOUR;
import static java.time.temporal.ChronoField.SECOND_OF_MINUTE;
public static final DateTimeFormatter MY_TIME;
static {
MY_TIME = new DateTimeFormatterBuilder()
.appendValue(HOUR_OF_DAY, 2)
.appendValue(MINUTE_OF_HOUR, 2)
.optionalStart()
.appendValue(SECOND_OF_MINUTE, 2)
.optionalStart()
.appendFraction(MICRO_OF_SECOND, 0, 6, true)
.toFormatter().withResolverStyle(ResolverStyle.STRICT);
}
I can process inputs just fine:
String text = "101530";
LocalTime lt = LocalTime.parse(text, MY_TIME);
or even
String text = "070907.0705";
LocalTime lt = LocalTime.parse(text, MY_TIME);
and
String text = "0000";
LocalTime lt = LocalTime.parse(text, MY_TIME);
But for some reason I cannot make sense of the API for handling leap second so the following always fails for me:
String text = "235960";
LocalTime lt = LocalTime.parse(text, MY_TIME);
How should I build my DateTimeFormatterBuilder
so that leap second is handled ?
Update: I really like the ResolverStyle.STRICT
, since it reject invalid inputs such as:
So I cannot use ResolverStyle.LENIENT
in this case, I simply want the extra special case for leap second.
Since this is of limited use for my users (editing of invalid time), I can handle this special case using simply:
if (text.length() >= 6 && "60".equals(text.substring(4, 6))) {
String newText = text.substring(0, 4) + "59" + text.substring(6);
return LocalTime.parse(newText, MY_TIME);
}
return LocalTime.parse(text, MY_TIME);
It seems this is a generally accepted hack: