【问题标题】:Parsing date and AM/PM using java 8 DateTime API使用 java 8 DateTime API 解析日期和 AM/PM
【发布时间】:2015-08-24 10:28:34
【问题描述】:

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

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

使用以前的java.text.SimpleDateFormat API,解析工作如预期使用此模式。

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

LocalDateTime.parse("17/02/2015 PM", DateTimeFormatter.ofPattern("dd/MM/yyyy aa"));

我遇到了以下异常:

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)

如果我将模式切换为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

奇怪的是,当我做反向操作时,格式,它工作正常:

 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")));

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

java.time.DateTimeFormatter 的 javadoc 说(§Resolving,步骤 #6):

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

我的理解是,解析 LocalDateTime 的字段时间是强制性的...有没有办法仅使用 AM/PM 字段解析时间部分?

【问题讨论】:

  • 嗯,嗯,你有上午和下午,但没有关联的时间......你希望日期被解析成什么?
  • 我希望时间部分设置为 12:00:00 或 00:00:00。它曾经与java.text.SimpleDateFormat一起工作。
  • 好吧,SimpleDateFormat 甚至能够解析它是一个奇怪的极端情况;毕竟它甚至不是一个有效的日期。为什么您没有正确格式化开始的日期?
  • 是的,这可能是SimpleDateFormat 中的一个极端案例。如果我负责格式化日期,我肯定会使用 ISO DateTime 格式...... :-) 我自己没有找到解决方案,所以我只是问是否有人有一个......如果它不被支持,我肯定会找到另一种解决方案,例如添加小时和分钟字段之类的......
  • 如果要解析的文本中只有 AM/PM 信息,那么时间必须是午夜或中午是不合逻辑的。它可以是任何时间,因为 AM/PM 只是确定哪个 半天 是相关的。 JSR-310(java.time-package)的设计者正确地拒绝了这种要求库凭空创造数据的情况。这里至少需要上午/下午的时间作为补充。

标签: java java-8 java-time


【解决方案1】:

您可以通过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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-06
    • 1970-01-01
    • 1970-01-01
    • 2011-04-06
    相关资源
    最近更新 更多