Context
2018年12月31日的時(shí)候,美國(guó)同事踩了一個(gè)Java SimpleDateFormat的坑下隧,導(dǎo)致某個(gè)查詢ElasticSearch的服務(wù)Down了8個(gè)小時(shí)。我也是第一次看到這個(gè)坑,借此機(jī)會(huì)整理一下宠能,以免以后自己也犯同樣的錯(cuò)誤。
Code Snippet
我抽象了相應(yīng)的代碼片段如下:
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
上面這個(gè)代碼的輸出為2019.12.31
磁餐,注意2018年變成了2019年违崇。
Details
美國(guó)同事貼心的引用了一個(gè)社區(qū)的Bug,但這個(gè)其實(shí)不算bug诊霹,而是對(duì)SimpleDateFormat誤用的結(jié)果羞延。
下面貼一張從官方文檔截取的部分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個(gè)概念,Year 和 Week year脾还。前者很好理解伴箩,就是正常日歷上的年份,后者就有點(diǎn)繞了鄙漏,下面參考官方文檔來(lái)解釋一下嗤谚。簡(jiǎn)單來(lái)說,2018年12月31日怔蚌,正好是2019 Week-year的第一周第一天呵恢。因此"YYYY"的結(jié)果是2019。
- 將代碼修改一下媚创,
SimpleDateFormat df = new SimpleDateFormat("yyyy.MM.dd");
后渗钉,就能得到正確的結(jié)果了, - 類似的還有"D"和"d"钞钙。因此大多數(shù)情況下都應(yīng)該要選用"y"和"d"鳄橘。