Java SimpleDateFormat 中易踩的坑

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
  1. 这里有2个概念,YearWeek year。前者很好理解,就是正常日历上的年份,后者就有点绕了,下面参考官方文档来解释一下。简单来说,2018年12月31日,正好是2019 Week-year的第一周第一天。因此"YYYY"的结果是2019。
  2. 将代码修改一下,SimpleDateFormat df = new SimpleDateFormat("yyyy.MM.dd");后,就能得到正确的结果了,
  3. 类似的还有"D"和"d"。因此大多数情况下都应该要选用"y"和"d"。

推荐阅读更多精彩内容