使用日期时间使用可选节解析"integer"时间格式化程序



我有一些DB,我有一些自定义的LocalTime格式,我正在尝试为它构建一个DateTimeFormatter

有以下规则:

  • 0 => 00:00
  • 10 => 00:10
  • 111 => 1:11
  • 101 => 1:01
  • 1111 => 11:11

这样的格式化程序中可以有带有 [] 的可选部分,但我不确定是否可以将这些规则应用于这样的格式化程序。

当使用DateTimeFormatter.ofPattern("Hmm")时,可以解析900和1111,但11(显然)不能。

但是使用 [H]mm 时,900 和 1111 都不能解析。

但是[HH]mm,可以解析 1111,但不能解析 900

我尝试了类似的东西

    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("[HH][m]m");
    // or
    formatter = DateTimeFormatter.ofPattern("[H]mm");
    System.out.println(LocalTime.parse("1111",formatter));
    System.out.println(LocalTime.parse("900",formatter));
    System.out.println(LocalTime.parse("1",formatter));
    System.out.println(LocalTime.parse("11",formatter));
    System.out.println(LocalTime.parse("201",formatter));
    System.out.println(LocalTime.parse("1000",formatter));
    System.out.println(LocalTime.parse("0",formatter));
// assertions
    assertThat(LocalTime.parse("1111",formatter), CoreMatchers.equalTo(LocalTime.of(11,11)));
    assertThat(LocalTime.parse("900",formatter), CoreMatchers.equalTo(LocalTime.of(9,00)));
    assertThat(LocalTime.parse("1",formatter), CoreMatchers.equalTo(LocalTime.of(0,1)));
    assertThat(LocalTime.parse("201",formatter), CoreMatchers.equalTo(LocalTime.of(2,1)));
    assertThat(LocalTime.parse("1000",formatter), CoreMatchers.equalTo(LocalTime.of(10,0)));
    assertThat(LocalTime.parse("0",formatter), CoreMatchers.equalTo(LocalTime.of(0,0)));

但这不起作用,抛出异常,例如

线程"main"中的异常 java.time.format.DateTimeParseException:无法在索引 4 处解析文本"1111"

DateTimeFormatter中没有模式可以解析您想要的内容。此外,DateTimeFormatterBuilder无法帮助您。主要问题是解析器是贪婪的,所以任何设置的东西都会解析前一位/两位数字作为小时,留下剩下的几分钟。这与您的规格不符。

选项 1:

使用此方法:

DateTimeFormatter f = new DateTimeFormatterBuilder()
    .appendValue(HOUR_OF_DAY)
    .appendValue(MINUTE_OF_HOUR, 2)
    .toFormatter();
LocalTime time = LocalTime.parse("0000" + str, f);

这种方法使模式规则,具有固定的分钟位数。应该注意的是,DateTimeFormatter.ofPattern("Hmm")也可以,但我使用了上面的长形式来使其更明显。

选项 2:

编写处理上面定义的整数格式的 TemporalField 实现。然后在DateTimeFormatterBuilder中使用它。对于这种需求来说,这要困难得多,而且矫枉过正,但为了完整起见,这里提到了这一点。

这是一个解决方案:

DateTimeFormatter formatter = new DateTimeFormatterBuilder()
            .optionalStart()
            .appendValue(ChronoField.HOUR_OF_DAY, 2)
            .appendValue(ChronoField.MINUTE_OF_HOUR, 2)
            .optionalEnd()
            .optionalStart()
            .appendValue(ChronoField.HOUR_OF_DAY, 1)
            .appendValue(ChronoField.MINUTE_OF_HOUR, 2)
            .optionalEnd()
            .optionalStart()
            .parseDefaulting(ChronoField.HOUR_OF_DAY, 0)
            .appendValue(ChronoField.MINUTE_OF_HOUR)
            .optionalEnd()
            .toFormatter();

最新更新