用leap秒来解析持续时间,例如00:00:60

时间:2018-09-25 09:12:49

标签: java datetime date-formatting java-time dateformatter

我该如何解析leap秒到秒的持续时间?

例如,我们从另一个服务接收以下持续时间00:00:60,这意味着1分钟,但是Java 8 DateTimeFormatter.ofPattern("HH:mm:ss[.SSS]")抛出了

java.time.format.DateTimeParseException: Text '00:00:60' could not be parsed: Invalid value for SecondOfMinute (valid values 0 - 59): 60

这很有意义,因为Java使用的ISO标准中没有60秒的概念。

我想避免使用String::replace(如在类似情况的其他SO答案中所建议),并尽可能避免使用外部库。

这是引发异常的当前代码:

private static final DateTimeFormatter TIME_FORMATTER = DateTimeFormatter.ofPattern("HH:mm:ss[.SSS]");

public static Integer parseToSeconds(String durationText) {

    return LocalTime.parse(durationText, TIME_FORMATTER).toSecondOfDay();
}

2 个答案:

答案 0 :(得分:1)

这是我解决问题的方法:

private static final DateTimeFormatter TIME_FORMATTER = DateTimeFormatter.ofPattern("HH:mm:ss[.SSS]");

public static long parsesToSeconds(String durationText) {
    Duration timeSum = Duration.ZERO;
    // Reformat to ISO 8601
    durationText = durationText.replaceFirst("(\\d{2}):(\\d{2}):(\\d{2}(?:\\.\\d+)?)", "PT$1H$2M$3S");

    timeSum = timeSum.plus(Duration.parse(durationText));

    return timeSum.getSeconds();
}

归功于Ole V.V.他的答案在这里:https://stackoverflow.com/a/52315938/2240409

答案 1 :(得分:1)

这是我们宽大的解析器风格。

    String durationText = "00:00:60";
    DateTimeFormatter lenientTimeFormatter = DateTimeFormatter.ISO_LOCAL_TIME
            .withResolverStyle(ResolverStyle.LENIENT);
    int seconds = LocalTime.parse(durationText, lenientTimeFormatter).toSecondOfDay();
    System.out.println(seconds);

此代码段的输出为:

  

60

如果您的60秒确实是持续时间而不是一天中的某个时间,那么我真的不喜欢它。然后,我想像您自己回答一样解析为Duration。我知道带有难以理解的正则表达式的String.replace也不是一个很好的解决方案,但我仍然认为我宁愿假装持续时间是一天中的某个时间(如果这是完全错误的), 。我只是以为无论如何我都会提出这个选择,让您根据自己的实际情况和偏好来做出自己的选择。