什么?一键穿越到2020-12-31?什么啊。今天明明才1月2号。刚刚享受过元旦的快乐,你就告诉我又到年底了?
nonono,实际上是今天我在V站看到了这篇帖子。觉得很有意思。所以拿来分享一下。
写代码的时候,你常用的时间格式是YYYY-MM-dd
,还是yyyy-MM-dd
呢?
可能这些的区别,你曾经在上课的时候听老师提起过。也可能你从来没有注意过他们的区别。但是无论如何,今年已经2020了。你可一定要搞清楚这些的区别!
我们先来复现一下贴中的BUG:
1 |
|
如果你不认得LocalDateTime和DateTimeFormatter的话,那你真的是Out啦,不要再用Date和SimpleDateFormatter啦。快去了解一下这两个崭新的类吧。
话归正题,让我们来看看结果是什么:
什么鬼啊,为什么2019-12-28下面直接就是2020-12-29了?
其实这个问题在 Stack OverFlow 上很早就有讨论了。Y returns 2012 while y returns 2011 in SimpleDateFormat.
我们去Java Doc上翻一翻,很容易就找到答案了:Y
是“Week-Based-Year”,而y
是“Year”。
那什么是 “Week-Based-Year”呢,我找到的一篇文章中这样解释:
Week number according to the ISO-8601 standard, weeks starting on Monday. The first week of the year is the week that contains that year’s first Thursday (=’First 4-day week’). The highest week number in a year is either 52 or 53.
根据 ISO-8601 标准,一周始于周一,一年的第一周是包含这一年第一个星期四的那一周。因此,2020-01-02,也就是今天,是周四。因此,这周就是2020年第一周。所以作为“Week Year”,YYYY
就会把同在本周的2019-….
写到这里我迷惑了。看看上面的运行结果。如果说因为这周是2020第一周,所以把周一周二的12-30、12-31归于2020年,我理解。但是12-29呢?它是属于上周日啊?
于是我就去找了其他地方的文章,最后在掘金看到有人说:YYYY
是week-based-year
,表示:当天所在的周属于的年份,一周从周日开始,周六结束,只要本周跨年,那么这周就算入下一年。所以2019年12月29日那天在这种表述方式下就已经 2020 年了。
这样说的话就解释了运行结果了。但是我又运行了一下代码:
1 |
|
运行结果如下:
难道这不是按照ISO-8601来的吗?所以上面我阅读ISO标准的时候才会被迷惑?
这就留待日后我去找寻答案了。
附表:All letters ‘A’ to ‘Z’ and ‘a’ to ‘z’ are reserved as pattern letters. The following pattern letters are defined:
Symbol Meaning Presentation Examples ------ ------- ------------ ------- G era text AD; Anno Domini; A u year year 2004; 04 y year-of-era year 2004; 04 D day-of-year number 189 M/L month-of-year number/text 7; 07; Jul; July; J d day-of-month number 10 Q/q quarter-of-year number/text 3; 03; Q3; 3rd quarter Y week-based-year year 1996; 96 w week-of-week-based-year number 27 W week-of-month number 4 E day-of-week text Tue; Tuesday; T e/c localized day-of-week number/text 2; 02; Tue; Tuesday; T F week-of-month number 3 a am-pm-of-day text PM h clock-hour-of-am-pm (1-12) number 12 K hour-of-am-pm (0-11) number 0 k clock-hour-of-am-pm (1-24) number 0 H hour-of-day (0-23) number 0 m minute-of-hour number 30 s second-of-minute number 55 S fraction-of-second fraction 978 A milli-of-day number 1234 n nano-of-second number 987654321 N nano-of-day number 1234000000 V time-zone ID zone-id America/Los_Angeles; Z; -08:30 z time-zone name zone-name Pacific Standard Time; PST O localized zone-offset offset-O GMT+8; GMT+08:00; UTC-08:00; X zone-offset 'Z' for zero offset-X Z; -08; -0830; -08:30; -083015; -08:30:15; x zone-offset offset-x +0000; -08; -0830; -08:30; -083015; -08:30:15; Z zone-offset offset-Z +0000; -0800; -08:00; p pad next pad modifier 1 ' escape for text delimiter '' single quote literal ' [ optional section start ] optional section end # reserved for future use { reserved for future use } reserved for future use