DateTimeFormatter 为边缘情况提供错误格式[重复]
Posted
技术标签:
【中文标题】DateTimeFormatter 为边缘情况提供错误格式[重复]【英文标题】:DateTimeFormatter giving wrong format for edge cases [duplicate] 【发布时间】:2019-01-07 08:00:15 【问题描述】:DateTimeFormatter
未按照以下 sn-p 提供 2018 年 12 月 30 日和 31 日的正确格式。
final String DATE_FORMAT = "YYYYMM";
DateTimeFormatter dateFormat = DateTimeFormatter.ofPattern(DATE_FORMAT);
LocalDateTime startDate = LocalDateTime.of(2018,12,29,5,0,0);
System.out.println(startDate.format(dateFormat));
//prints 201812
LocalDateTime startDate = LocalDateTime.of(2018,12,30,5,0,0);
System.out.println(startDate.format(dateFormat));
//prints 201912 <------ should be 201812
LocalDateTime startDate = LocalDateTime.of(2018,12,31,5,0,0);
System.out.println(startDate.format(dateFormat));
//prints 201912 <------ should be 201812
这是预期的行为还是 DateTimeFormatter 存在错误?
【问题讨论】:
你改代码后重新编译了吗? YYYY是周年,yyyy是年 请仔细阅读SimpleTimeFormatter javadoc。请注意,这是针对 Java 10 的。 你需要了解 YYYY & yyyy 的机制。 yyyy 指定日历年,而 YYYY 指定年份(“一年中的一周”),用于 ISO 年-周日历 @Kandy 这就是为什么我链接到非常流行的 JodaTime 库,它“是 Java SE 8 之前的 Java 事实标准日期和时间库”,并将Y
处理为 year of era (>=0)
- 除非明确记录合规性,否则不要假设哪个解析器/格式化程序实现了哪个(部分)标准。
【参考方案1】:
这是预期的行为。 YYYY
代表“week-based-year”,与日历年不同(参见JavaDoc)
您很可能想使用yyyy
,意思是“时代”
【讨论】:
【参考方案2】:YYYY 是周年,yyyy 是年
所以 Change final String DATE_FORMAT = "YYYYMM";
ro final String DATE_FORMAT = "yyyyMM";
应该会给你正确的结果。有关模式的更多信息,请参阅javadoc of DateTimeFormatter。
2019 年的第一周从 2018 年 12 月 30 日开始。请参阅此link 了解有关早年的更多信息
【讨论】:
@OleV.V.在 Java 版本 7 之前,DateFormatter 的文档并不好,所以我喜欢使用 SimpleDateFormat 文档。我已经看到它在 Java 8+ 版本中被更改了提示【参考方案3】:y
用于“时代”,而Y
用于week-based-year
替换:
final String DATE_FORMAT = "YYYYMM";
到:
final String DATE_FORMAT = "yyyyMM";
【讨论】:
以上是关于DateTimeFormatter 为边缘情况提供错误格式[重复]的主要内容,如果未能解决你的问题,请参考以下文章
DateTimeFormatter 的操作与使用 -- 通俗易懂
在 1 月首次使用 DateTimeFormatter 会导致年份值无效