【发布时间】:2015-08-24 10:28:34
【问题描述】:
我正在尝试使用 java 8 DateTime API 解析日期时间字符串。
要解析的字符串包含日期、月份、年份和 AM/PM 标记,例如 17/02/2015 PM。
我使用以下模式:dd/MM/yyyy aa,并且我希望解析的 LocalDateTime 时间部分设置为 12:00:00 或 00: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 AM 和17/02/2015 PM。
java.time.DateTimeFormatter 的 javadoc 说(§Resolving,步骤 #6):
- 如果一天中至少有一个小时可用,则会形成 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)的设计者正确地拒绝了这种要求库凭空创造数据的情况。这里至少需要上午/下午的时间作为补充。