文章目录
- Java日期时间格式化符号
- ISO 8601中的日期时间
- ISO 8601标准的定义
- ISO 8601日期时间格式
 
- 周数年份
- ISO 8601中的周数年份
- Java中的周数年份
 
- Java跨年日期格式化BUG
- 注意事项
Java日期时间格式化符号
JDK官网截图:
 
格式化符号梳理:
| 符号 | 描述 | 符号用法 | 示例 | 
|---|---|---|---|
| G | 公历纪元 | G:公历纪元 | AD(公元) 、BC(公元前) | 
| y | 年份 | yy:两位年份yyyy:四位年份 | 242024 | 
| Y | 年份(ISO周数所在年份,可能跨年) | YY:两位年份YYYY:四位年份 | 252025 | 
| M | 月份 | M:月份(不带零)MM:月份(不带零)MMM:月份缩写MMMM:月份全写 | 101Jan、一月January、一月 | 
| d | 日 | d:单位数字或两位数字dd:两位数字 | 606 | 
| H | 小时(24小时制) | H:小时(24小时制,不带零)HH:小时(24小时制,带零) | 909 | 
| h | 小时(12小时制) | h:小时(12小时制,不带零)hh:小时(12小时制,带零) | 909 | 
| m | 分钟 | m:分钟(不带零)mm:分钟(带零) | 505 | 
| s | 秒 | s:秒(不带零)ss:秒(带零) | 303 | 
| S | 毫秒 | S:毫秒(不带零)SSS:毫秒(带零) | 56056 | 
| E | 星期 | EEE:星期缩写EEEE:星期全写 | Mon、星期二Monday、星期二 | 
| u | 星期(数字) | u:星期(数字) | 1、2、3、4、5、6、7 | 
| w | 周数(年内的第几周) | w:年内第几周 | 2(表示年内的第2周) | 
| W | 周数(月内的第几周) | W:月内的第几周 | 2(该月的第2周) | 
| F | 月份中的第几个周几 | F:月份中的第几个星期几 | 2(该月的第二个星期x) | 
| D | 年中天数 | D:一年中的第几天 | 6(一年中的第6天) | 
| a | AM/PM | a:上午或下午的标记 | AM、PM、上午、下午 | 
| Z | 时区偏移 | Z:时区偏移(格式:+0800) | +0800(UTC+8时区) | 
| X | 时区偏移(ISO 8601格式) | X:时区偏移(ISO 8601格式,格式:+08) | +08(UTC+8时区) | 
| z | 时区(时区名称) | z:时区缩写zzzz:时区全称 | CST(时区缩写)中国标准时间(时区全称) | 
| ' | 文字字符(原样输出) | '':原样输出字符 | '星期天'(原样输出 :星期天) | 
ISO 8601中的日期时间
ISO 8601标准的定义
- 一年中的第一个周:一年中的第一个周是包含该年的第一个星期四的周。这意味着该年的第一个周可能会跨越前一年和当前年。
- 每周的起始日:ISO-8601将周的起始日定义为星期一。
- 每周的结束日:ISO-8601将周的结束日定义为星期日。
ISO 8601日期时间格式
ISO 8601规定了一种标准的日期和时间表示方式,以确保在全球范围内的一致性。以下是ISO 8601的基本格式:
-  日期格式:YYYY-MM-DD - YYYY表示四位数的年份
- MM表示两位数的月份
- DD表示两位数的日期
 
-  时间格式:hh:mm:ss - hh表示两位数的小时
- mm表示两位数的分钟
- ss表示两位数的秒
 
-  日期时间格式:YYYY-MM-DDThh:mm:ss - 使用字母’T’来分隔日期和时间
 
周数年份
在日期时间处理时,通常有两种不同的年份表示方式:
-  常规年份:这是基于日历年(公历年),即我们通常使用的年份。 例如:2024年12月31日的年份是2024。 
-  周数年份:周数年份是根据一年的第一个完整星期来定义的,通常在需要进行国际化或跨年时间计算时使用。 例如:ISO 8601 标准规定了一个系统,其中一周的第一天是星期一,并且第一周是包含该年1月4日的那一周。周数年份与常规年份可能并不完全一致。2024年12月31日的周数年份是2025。 
ISO 8601中的周数年份
在日期时间处理时,通常有两种不同的年份表示方式:
-  常规年份:这是基于日历年(公历年),即我们通常使用的年份。 例如:2025年1月1日的年份是2025。 
-  ISO周数年份:这是基于ISO 8601标准的年份,周数是基于一周中的第一天(周一)来计算的。 ISO 8601定义: 一年的第一周是包含该年首个周四的那一周,所以ISO年份可能与日历年份不同。例如:2024年12月31日的ISO周数年份是2025。 
Java中的周数年份
需要注意:分析发现Java中的周数年份与ISO 8601的是有区别的(正确性不太确定,至少使用SimpleDateFormat格式化是这样的)。
Java中和ISO 8601中的周数年份(Y)对比:
-  Java 中的周数年份( 正确性不太确定):- 一年的第一周:是包含1月1日的那一周,如果该周(星期日 ~ 星期六)有几天在上一年中,那么这几天所属年份也为该年
- 每周的起始日:星期日
- 每周的结束日:星期六
 
-  ISO 8601中的周数年份: - 一年的第一周:是包含该年首个周四的那一周,如果该周(星期一 ~ 星期日)有几天在上一年中,那么这几天所属年份也为该年
- 每周的起始日:星期一
- 每周的结束日:星期日
 
Java跨年日期格式化BUG
误用YYYY可能导致年份错误,具体原因参考上文,需改为使用yyyy。
例如,时间为2024-12-31
- yyyy-MM-dd,输出:2024-12-31
- YYYY-MM-dd,输出:2025-12-31
注意事项
- 在一些西方国家,通常把星期日作为一周的第一天;Java(使用SimpleDateFormat格式化)也是如此,把星期日作为一周的第一天。