Java - 解析日期/期间的优雅方式?

aph*_*rid 11 java datetime duration period java-8

根据ISO-8601标准,有4种表达间隔/持续时间的方式:

  1. 开始和结束,例如"2007-03-01T13:00:00Z/2008-05-11T15:30:00Z"

  2. 开始和持续时间,例如"2007-03-01T13:00:00Z/P1Y2M10DT2H30M"

  3. 持续时间和结束,例如"P1Y2M10DT2H30M/2008-05-11T15:30:00Z"

  4. 持续时间,例如"P1Y2M10DT2H30M",带有附加的上下文信息

仅使用Java 8(没有Joda,扩展等),是否有处理案例1-3的优雅方法?

我知道Duration.Parse()并且Period.Parse(),但我想知道是否有一种处理这4种情况的优雅方式.例如:

String datePeriod = "2016-07-21/P6D";
String twoDates   = "2016-07-21/2016-07-25";

Duration d = Duration.parse(datePeriod); // DateTimeParseException
Duration p = Duration.parse(twoDates); // same
Run Code Online (Sandbox Code Playgroud)

我目前的思维过程非常草率,我百分百肯定有更好的方法.对于每种情况,使用嵌套的try/catch块分别处理4个案例,这看起来有点像反模式,如果有的话.(拆分/,解析第一个块的日期,检查错误,解析第一个块的时间段,解析第二个块的日期,检查错误......你明白了)

任何提示将非常感谢!

-

此外,ISO 8601时间间隔解析在Java中的答案并没有真正帮助我,因为最顶层的答案只关心这些PT...东西.

Mak*_*oto 6

没有真正的反模式来分裂这些东西.Oracle已经将这些单独的解析器的职责分开了,如果我们想在这种编排中一起使用它们,我们应该确保以合理的方式再次将这些部分拆分.

也就是说,我有一个与核心Java 8兼容的解决方案,并且使用Function了一些自定义类.为了简洁,我将省略自定义bean,因为它们是相当基本的,以及主升降机在Functions中完成的事实.

请注意,为了将'Z'识别为有效条目,您必须解析DateTimeFormatter.ISO_DATE_TIME.此外,为了确保您的持续时间得到适当的选择,"PT"请在文本中添加适合持续时间的文本.从现有字符串中获取这种细节的更智能方法是我为读者留下的练习.

Function<String, Range> convertToRange = (dateString) -> {

    String[] dateStringParts = dateString.split("/");
    return new Range(LocalDateTime.parse(dateStringParts[0], DateTimeFormatter.ISO_DATE_TIME),
            LocalDateTime.parse(dateStringParts[1], DateTimeFormatter.ISO_DATE_TIME));
};

Function<String, DurationAndDateTime> convertToDurationAndDateTime = (dateString) -> {
    String[] dateStringParts = dateString.split("/");
    String[] durationAndPeriodParts = dateStringParts[1].split("T");
    return new DurationAndDateTime(Period.parse(durationAndPeriodParts[0]),
            Duration.parse("PT" + durationAndPeriodParts[1]),
            LocalDateTime.parse(dateStringParts[0], DateTimeFormatter.ISO_DATE_TIME));
};


Function<String, DurationAndDateTime> convertToDateTimeAndDuration = (dateString) -> {
    String[] dateStringParts = dateString.split("/");
    String[] durationAndPeriodParts = dateStringParts[0].split("T");
    return new DurationAndDateTime(Period.parse(durationAndPeriodParts[0]),
            Duration.parse("PT" + durationAndPeriodParts[1]),
            LocalDateTime.parse(dateStringParts[1], DateTimeFormatter.ISO_DATE_TIME));
};

Function<String, DurationOnly> convertToDurationOnlyRelativeToCurrentTime = (dateString) -> {
    String[] durationAndPeriodParts = dateString.split("T");
    return new DurationOnly(Period.parse(durationAndPeriodParts[0]),
            Duration.parse("PT" + durationAndPeriodParts[1]));
};
Run Code Online (Sandbox Code Playgroud)