Parsing an ISO 8601 date in Java8 when all fields (including separators, but not including years) are optional

前端 未结 4 1665
北海茫月
北海茫月 2021-01-15 06:26

I have a requirement for parsing ISO8601 formatted strings in Java with various levels of accuracy. Some examples of the string I need to parse are:

  • 2018
4条回答
  •  小鲜肉
    小鲜肉 (楼主)
    2021-01-15 06:40

    Well that took me longer than I had expected. The only valid parser is:

    DateTimeFormatter dtf = new DateTimeFormatterBuilder()
            .appendValue(ChronoField.YEAR, 4)
            .appendPattern("[['-']MM[['-']dd[['T']HH[[':']mm[[':']ss['.'SSS]]]]]]")
            .parseDefaulting(ChronoField.MONTH_OF_YEAR, 1)
            .parseDefaulting(ChronoField.DAY_OF_MONTH, 1)
            .parseDefaulting(ChronoField.HOUR_OF_DAY, 0)
            .parseDefaulting(ChronoField.MINUTE_OF_HOUR, 0)
            .parseDefaulting(ChronoField.SECOND_OF_MINUTE, 0)
            .parseDefaulting(ChronoField.NANO_OF_SECOND, 0)
            .toFormatter();
    
    String[] s = {
            "2018",
            "2018-10",
            "2018-10-15",
            "2018-10-15T12:00",
            "2018-10-15T12:00:30",
            "2018-10-15T12:00:30.123",
            "20181015",
            "201810151200",
            "20181015120030",
            "20181015120030.123",
            "20181015T12:00:30.123"
    };
    for (String line : s) {
      System.out.println(LocalDateTime.parse(line, dtf));
    }
    

    The problem is that yyyy creates a ValueParser(minWidth=4, maxWidth=19, SignStyle.PAD_EXEEDS) which parses the date 20181015 as year=20181015 as an example. So we have to restrict the digit width of year to 4.

    The documentation states:

    Year: The count of letters determines the minimum field width below which padding is used.

    But does not specify a maximum width.

提交回复
热议问题