无法将字符串解析为LocalDate(Java 8)

32

我的输入是一个表示日期的字符串,格式为"01-07-2015"代表2015年7月1日。我正在尝试将其解析成java.time.LocalDate变量:

final DateTimeFormatter DATE_FORMAT = DateTimeFormatter.ofPattern("dd-MM-YYYY");
final String input = "01-07-2015";
final LocalDate localDate = LocalDate.parse(input, DATE_FORMAT);
根据 DateTimeFormatter JavaDoc 的文档,我期望这会起作用。然而,我被一个非常友好和有用的消息所打招呼:

Caused by: java.time.DateTimeException: Unable to obtain LocalDate from TemporalAccessor: {DayOfMonth=1, MonthOfYear=7, WeekBasedYear[WeekFields[MONDAY,4]]=2015},ISO of type java.time.format.Parsed

我不太明白这个异常告诉我的是什么。有人能解释一下出了什么问题吗?

13
你应该选择 yyyy 而不是 YYYY - KV Prajapati
2个回答

42

年份需要使用小写的 y:

final DateTimeFormatter DATE_FORMAT = DateTimeFormatter.ofPattern("dd-MM-yyyy");

大写字母 Y 用于表示周年。有关详细信息,请参见DateTimeFormatter的javadoc


4
纯属好奇,错误信息与Y代表周年而y代表年份有什么关系? - mthmulders
4
错误信息显示 {DayOfMonth=1, MonthOfYear=7, WeekBasedYear[WeekFields[MONDAY,4]]=2015},这表示它将你输入的字符串中的数字1解析为日期中的“日”(因为你在格式中使用了“d”),数字7被解析为日期中的“月”(因为格式中有“M”),而2015年则被理解为基于周的年份(又称周年)(因为格式中有“Y”)。 - Kejml
@mthmulders 有时候异常信息很糟糕。尽管如此,该异常并不算太糟糕,它确实告诉了你它试图将“YYYY”解析为什么。我查了一下java datetimeformatter weekbasedyear,第一个结果将我带到了这里,上面列出了标识符类型及其含义。 - Chris Cirefice

23
回答:问题的答案是使用 'y' 而不是 'Y'。
解释错误消息,让我们进行分解:
“无法从TemporalAccessor获取LocalDate”
这意味着它无法从TemporalAccessor(提供类似哈希表的日期时间字段访问的低级接口)中创建所请求的 LocalDate。
“类型为java.time.format.Parsed”
这表示传递给方法的对象类型为 java.time.format.Parsed。这是解析的标准输出类型,并包含所有已解析的信息。
"{DayOfMonth=1,MonthOfYear=7,WeekBasedYear [WeekFields [MONDAY,4]] = 2015},ISO"
这是由解析得到的 java.time.format.Parsed 对象的 toString()形式。它表示解析了四个内容:
- “DayOfMonth=1”,解析值为1的月中日。 - “MonthOfYear=7”,解析值为7的年中月份。 - “WeekBasedYear [WeekFields [MONDAY,4]] = 2015”,解析值为2015的基于周的年份。 - “ISO”,这是 ISO 日历系统(默认值)。
由于不能通过 DayOfMonth + MonthOfYear + WeekBasedYear 的组合产生 LocalDate,因此会引发异常。
请注意,“[WeekFields [MONDAY,4]]” 部分指的是有多种定义一周的方式,在美国一周从星期日开始,但在 ISO 标准和欧盟中则从星期一开始。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接