使用java 8 DateTime API解析日期和AM/PM

Ben*_*min 11 java java-8 java-time

我正在尝试使用java 8 DateTime API解析日期时间字符串.

要解析的字符串包含日期,月份,年份和AM/PM标记,例如17/02/2015 PM.我使用以下模式:dd/MM/yyyy aa我希望解析的LocalDateTime时间部分设置为12:00:0000:00:00取决于AM/PM标记.

使用以前的java.text.SimpleDateFormatAPI,解析使用此模式按预期工作.

但是当我使用java 8 DateTime API并运行以下代码时:

LocalDateTime.parse("17/02/2015 PM", DateTimeFormatter.ofPattern("dd/MM/yyyy aa"));
Run Code Online (Sandbox Code Playgroud)

我得到以下异常:

Exception in thread "main" java.lang.IllegalArgumentException: Too many pattern letters: a
at java.time.format.DateTimeFormatterBuilder.parseField(DateTimeFormatterBuilder.java:1765)
at java.time.format.DateTimeFormatterBuilder.parsePattern(DateTimeFormatterBuilder.java:1604)
at java.time.format.DateTimeFormatterBuilder.appendPattern(DateTimeFormatterBuilder.java:1572)
at java.time.format.DateTimeFormatter.ofPattern(DateTimeFormatter.java:534)
Run Code Online (Sandbox Code Playgroud)

如果我将模式切换到dd/MM/yyyy a那时我得到了以下异常:

Exception in thread "main" java.time.format.DateTimeParseException: Text '17/02/2015 PM' could not be parsed: Unable to obtain LocalDateTime from TemporalAccessor: {AmPmOfDay=1},ISO resolved to 2015-02-17 of type java.time.format.Parsed
    at java.time.format.DateTimeFormatter.createError(DateTimeFormatter.java:1918)
    at java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:1853)
    at java.time.LocalDateTime.parse(LocalDateTime.java:492)
Caused by: java.time.DateTimeException: Unable to obtain LocalDateTime from TemporalAccessor: {AmPmOfDay=1},ISO resolved to 2015-02-17 of type java.time.format.Parsed
    at java.time.LocalDateTime.from(LocalDateTime.java:461)
    at java.time.LocalDateTime$$Lambda$7/474675244.queryFrom(Unknown Source)
    at java.time.format.Parsed.query(Parsed.java:226)
    at java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:1849)
    ... 2 more
Caused by: java.time.DateTimeException: Unable to obtain LocalTime from TemporalAccessor: {AmPmOfDay=1},ISO resolved to 2015-02-17 of type java.time.format.Parsed
    at java.time.LocalTime.from(LocalTime.java:409)
    at java.time.LocalDateTime.from(LocalDateTime.java:457)
    ... 5 more
Run Code Online (Sandbox Code Playgroud)

当我进行反向操作,格式化时,它也很奇怪:

 System.out.println(LocalDateTime.of(2015, 02, 17, 0, 0, 0).format(DateTimeFormatter.ofPattern("dd/MM/yyyy a")));
 System.out.println(LocalDateTime.of(2015, 02, 17, 12, 0, 0).format(DateTimeFormatter.ofPattern("dd/MM/yyyy a")));
Run Code Online (Sandbox Code Playgroud)

分别打印17/02/2015 AM17/02/2015 PM.

javadoc java.time.DateTimeFormatter表示(§Resolving,step#6):

  1. 如果至少有一个小时的可用时间,则形成LocalTime.这涉及提供分钟,秒和小数秒的默认值.

我的理解是,每天的字段时间是解析LocalDateTime所必需的......是否有办法仅使用AM/PM字段解析时间部分?

Tag*_*eev 12

您可以通过以下方式设置不可用字段的默认值DateTimeFormatterBuilder.parseDefaulting:

DateTimeFormatter formatter = new DateTimeFormatterBuilder()
    .appendPattern("dd/MM/yyyy a")
    .parseDefaulting(ChronoField.HOUR_OF_AMPM, 0) // this is required
    .parseDefaulting(ChronoField.MINUTE_OF_HOUR, 0) // optional, but you can set other value
    .parseDefaulting(ChronoField.SECOND_OF_MINUTE, 0) // optional as well
    .toFormatter();
System.out.println(LocalDateTime.parse("17/02/2015 PM", formatter)); // 2015-02-17T12:00
System.out.println(LocalDateTime.parse("17/02/2015 AM", formatter)); // 2015-02-17T00:00
Run Code Online (Sandbox Code Playgroud)