⭐⭐⭐ Spring Boot 项目实战 ⭐⭐⭐ Spring Cloud 项目实战
《Dubbo 实现原理与源码解析 —— 精品合集》 《Netty 实现原理与源码解析 —— 精品合集》
《Spring 实现原理与源码解析 —— 精品合集》 《MyBatis 实现原理与源码解析 —— 精品合集》
《Spring MVC 实现原理与源码解析 —— 精品合集》 《数据库实体设计合集》
《Spring Boot 实现原理与源码解析 —— 精品合集》 《Java 面试题 + Java 学习指南》

摘要: 原创出处 http://www.iocoder.cn/Fight/YYYY-MM-dd-keng/ 「芋道源码」欢迎转载,保留摘要,谢谢!


🙂🙂🙂关注**微信公众号:【芋道源码】**有福利:

  1. RocketMQ / MyCAT / Sharding-JDBC 所有源码分析文章列表
  2. RocketMQ / MyCAT / Sharding-JDBC 中文注释源码 GitHub 地址
  3. 您对于源码的疑问每条留言将得到认真回复。甚至不知道如何读源码也可以请教噢
  4. 新的源码解析文章实时收到通知。每周更新一篇左右
  5. 认真的源码交流微信群。

1. 概述

下班回家的路上,习惯性打开 群聊,不是为了解答问题,而是不想错过任何一个装 x 的机会。这不,就有胖友聊到一个经典的“神坑”:错误使用 YYYY-MM-dd 格式化时间,导致生产翻车。

带有马赛克的群聊

2. 翻车示例

下面,艿艿带大家写一个翻车的 Java 示例代码:

import java.text.SimpleDateFormat;
import java.util.Calendar;

public class TestXXXXXXXXXXXXX {

public static void main(String[] args) {
// 创建 2020-12-31
Calendar calendar = Calendar.getInstance();
calendar.set(2020, Calendar.DECEMBER, 31);

// 演示 YYYY-MM-dd 输出示例
SimpleDateFormat dfYYYY = new SimpleDateFormat("YYYY-MM-dd");
System.out.println("YYYY-MM-dd 输出:" + dfYYYY.format(calendar.getTime()));

// 演示 yyyy-MM-dd 输出示例
SimpleDateFormat dfyyyy = new SimpleDateFormat("yyyy-MM-dd");
System.out.println("yyyy-MM-dd 输出:" + dfyyyy.format(calendar.getTime()));
}

}

讲道理,正确输出的时间格式化结果应该为 "2020-12-31",但是使用 YYYY-MM-dd 却是 "2021-12-31"。如下图所示:

翻车啦

3. 翻车原因

为什么使用 YYYY-MM-dd 格式化 "2020-12-31" 时间时,打印的结果是错误"2021-12-31" 呢?

我们打开 https://docs.oracle.com/javase/8/docs/api/java/time/format/DateTimeFormatter.html#patterns 文档,看看 YYYY 的定义描述,就非常好理解背后的原因:

官方文档

翻译君:YYYY 使用的是 week-based-year,当天所在的周属于的年份,一周从周日开始,周六结束。只要本周跨年,那么这周就算入下一年。

关键在于 “只要本周跨年,那么这周就算入下一年” 这句话!什么意思呢,打开日历,安排的明明白白。

日历 - 2020~12

因为 "2021-01-01" 属于 2021 年,而 "2020-12-31" 与其处于同一周,所以被 YYYY 格式化时,输出的肯定是 2021 啦。不仅仅如此,这个问题,从 "2020-12-27" 开始就已经存在。

我们再来打开日历到 2021 年的 12 月来瞅瞅,康康还会不会存在翻车的情况。

日历 - 2021~12

答案当然是,翻车

未来不过是历史的一再重演。

4. 怎么避免

问题的解决,非常容易,只要将 YYYY-MM-dd 修改成 yyyy-MM-dd 即可。

但是,仅仅这样就足够了吗?良心的艿艿,建议胖友一定要定义一个 DateUtil 工具类,并在其中将常用的日期格式都提供好,禁止在其它地方定义。

日历 - 2021~12

实际上,有良好 IDEA 使用习惯的胖友,绝对不会出现 YYYY 这样的问题,因为 IDEA 已经智能提醒

IDEA

一切 IDEA 警告,皆为错误,必须去解决。


End~继续抠脚。

我是艿艿,一个每天徘徊在煞笔牛啤的死胖子。

我

文章目录
  1. 1. 1. 概述
  2. 2. 2. 翻车示例
  3. 3. 3. 翻车原因
  4. 4. 4. 怎么避免