javadatetimeleap-second

Parsing LocalTime with leap second


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.


Solution

  • 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: