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 (&gt;=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 为边缘情况提供错误格式[重复]的主要内容,如果未能解决你的问题,请参考以下文章

Rails多态命名边缘情况

DateTimeFormatter 的操作与使用 -- 通俗易懂

在 1 月首次使用 DateTimeFormatter 会导致年份值无效

Java中的`DateTimeFormatter`格式化模式代码中的`uuuu`与`yyyy`?

边缘计算与云计算服务提供商

边缘计算在车路协同中的场景应用分析