Context
2018年12月31日的时候,美国同事踩了一个Java SimpleDateFormat的坑,导致某个查询ElasticSearch的服务Down了8个小时。我也是第一次看到这个坑,借此机会整理一下,以免以后自己也犯同样的错误。
Code Snippet
我抽象了相应的代码片段如下:
Date date = new SimpleDateFormat("yyyy.MM.dd").parse("2018.12.31");
System.out.println(date); // output is "Mon Dec 31 00:00:00 CST 2018"
SimpleDateFormat df = new SimpleDateFormat("YYYY.MM.dd");
System.out.println(df.format(date)); // output is 2019.12.31
上面这个代码的输出为2019.12.31
,注意2018年变成了2019年。
Details
美国同事贴心的引用了一个社区的Bug,但这个其实不算bug,而是对SimpleDateFormat误用的结果。
下面贴一张从官方文档截取的部分Date and Time Patters说明.
Letter | Date or Time Component | Examples |
---|---|---|
y | Year | 1996; 96 |
Y | Week year | 2009; 09 |
D | Day in year | 189 |
d | Day in month | 10 |
- 这里有2个概念,Year 和 Week year。前者很好理解,就是正常日历上的年份,后者就有点绕了,下面参考官方文档来解释一下。简单来说,2018年12月31日,正好是2019 Week-year的第一周第一天。因此"YYYY"的结果是2019。
- 将代码修改一下,
SimpleDateFormat df = new SimpleDateFormat("yyyy.MM.dd");
后,就能得到正确的结果了, - 类似的还有"D"和"d"。因此大多数情况下都应该要选用"y"和"d"。