1. 相应的业务场景
1.1 场景简介
正值2019年末,2020年初之际,系统日期时间为2019/12/31而系统报表却出现了2020/12/31的日期。
1.2 代码案例如下
2.Java中YYYY与yyyy的含义
2.1 时间字母含义表
2.2 Y的Week Year含义
Y代表的事Week Year,表示当天周所在的年份。这种方式将会将一年划分为52周或者事53周(类似闰年,每隔几年会增加一周)。Week Year的每周仅仅属于某一年,如果某年的第一周或者最后一周跨年,就会导致部分日期年份与实际不符合。
2.3 Week Year的两种标准
- ISO 8601:国际标准,每周从周一开始,每年的第一周至少包含 4 天
- Common:通用标准,每周从周日开始,每年的第一周至少包含 1 天
注:Calendar 对象可以通过 setFirstDayOfWeek 与 setMinimalDaysInFirstWeek 改变上面默认标准
Java 将会根据系统环境变量决定使用哪种标准,可以通过设置 Locale 改变方式。代码如下:
// 选择 20191229 这一天
Date date20191229 = DateUtils.parseDate("20191229", "yyyyMMdd");
// 将会输出 2020,使用 Common 。当前系统,Locale 默认值为 Locale.CHINA
System.out.println(DateFormatUtils.format(date20191229,"YYYY"));
// 将会输出 2019,使用 ISO 8601
System.out.println(DateFormatUtils.format(date20191229,"YYYY", Locale.FRANCE));
2.4 ISO 8601 标准之最后一周跨年以及第一周跨年的例子:
2015 年最后一周跨年,2016 前三天使用 YYYY 最后结果为 2015,时间看起来被回退了 |
2020 年第一周跨年,2019 年最后两天使用 YYYY 结果为 2020 |
3. 常用的日期格式
下面以 2019-12-31 06:06:06:666
时间为例
Letter | 含义 | Example |
---|---|---|
Y | Week Year | YYYY—>2020 |
y | 年 | yyyy——>2019 |
M | 月 | MM——>12 |
m | 分 | mm——–>06 |
D | 一年中天数 | DD——–>365 |
d | 一月中的天数 | dd———>06 |
H | 小时(0-23) | HH———>06 |
h | 小时(1-12) | hh———>06 |
S | 毫秒 | SSS———>666 |
总结:
- 第一,切记
YYYY
与yyyy
区别,年份最好统一使用yyyy
- 第二,可以使用阿里的 Alibaba Java Coding Guidelines 插件,这个插件可以检测出使用
YYYY
的代码 - 第三,阅读完整文档,消除 Bug 最好的的办法就是阅读完整的文档
帮助:
1. week_year
2. Serious Security: The decade-ending “Y2K bug” that wasn’t