昨天你用的 YYYY-MM-dd 被 CTO 捶了吗?

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

1. 概述

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

image.png

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"。如下图所示:

翻车啦

image.png

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 的定义描述,就非常好理解背后的原因:

image.png

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

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

image.png

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

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

image.png


答案当然是,翻车

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

4. 怎么避免

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

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

image.png

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

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

相关文章
|
存储 数据采集 安全
【PHP+VUE】手术麻醉临床信息管理系统源码
【PHP+VUE】手术麻醉临床信息管理系统源码
526 0
|
Rust 编译器 Linux
Rust编译过程讲解与环境准备
目前主流编译平台有,GNU、MSVC、LLVM。因为rustc调用了llvm,因此我们以LLVM为例,我们从C语言的编译过程聊,再对比Rust,看它们的编译过程有何差异。
479 0
|
编解码 前端开发 搜索推荐
什么是响应式设计?响应式设计的基本原理是什么?如何实现?
什么是响应式设计?响应式设计的基本原理是什么?如何实现?
2017 0
|
4月前
|
SQL 缓存 算法
Java 内存模型与 volatile:并发底层的轻量级同步核心
`volatile` 是JMM核心轻量级同步关键字,通过内存屏障禁用重排、借助MESI协议保障可见性,精准解决可见性与有序性(不保证原子性),是DCL单例、状态标志等场景的基石,堪称高效并发编程的“轻量级钥匙”。(239字)
302 7
Mac Source Tree拉代码报错,remote: CODING 提示: Authentication failed. remote: 认证失败,请确认您输入了正确的账号密码。 fatal...
Mac Source Tree拉代码报错,remote: CODING 提示: Authentication failed. remote: 认证失败,请确认您输入了正确的账号密码。 fatal...
2639 0
Mac Source Tree拉代码报错,remote: CODING 提示: Authentication failed. remote: 认证失败,请确认您输入了正确的账号密码。 fatal...
|
13天前
|
人工智能 自然语言处理 监控
阿里云百炼Token Plan团队版功能、优惠与使用解析:三档价格、企业权益与选型指南
2026年,企业级AI服务已从尝鲜阶段进入规模化落地期,团队协作、研发编程、内容创作、智能体开发等场景对大模型的依赖度持续攀升。传统按量计费模式易导致成本失控,单一模型套餐又难以满足多场景需求,企业亟需一套**预算可控、多模型兼容、团队管理便捷、数据安全合规**的AI服务方案。阿里云百炼平台推出的**Token Plan团队版**,正是为解决这些核心痛点而生的企业级订阅服务。
308 0
|
8月前
|
编解码 人工智能 搜索推荐
API,体育直播的“最强辅助”
看球卡顿、错过关键瞬间?背后“隐形骨架”竟是API!它实时同步比分、智能调度画质、多端联动、精准推荐,让观赛更流畅、智能、沉浸。从数据到互动,API正悄然改变你的看球体验。
500 150
|
10月前
|
机器学习/深度学习 算法 调度
基于遗传算法GA算法优化BP神经网络(Python代码实现)
基于遗传算法GA算法优化BP神经网络(Python代码实现)
638 0
|
Android开发 开发者
深入了解 Android 中的 RelativeLayout 布局
深入了解 Android 中的 RelativeLayout 布局
309 0
|
机器学习/深度学习 人工智能 算法
机器学习【教育领域及其平台搭建】
机器学习【教育领域及其平台搭建】
528 6