京东6.18大促主会场领京享红包更优惠

 找回密码
 立即注册

QQ登录

只需一步,快速开始

java.util.Date 为什么被嫌弃?

2026-1-6 17:47| 发布者: 架构师沉默| 查看: 26| 评论: 0

摘要: 沉默是金,总会发光大家好,我是沉默如果你是一名 Java 开发者,java.util.Date这个类你一定见过。甚至可以说——你没主动用过,也一定被它“坑”过。很多新同学都会有个疑问:明明是 JDK 自带的类,为什么老项目里


沉默是金,总会发光

大家好,我是沉默


如果你是一名 Java 开发者,java.util.Date这个类你一定见过。


甚至可以说——
你没主动用过,也一定被它“坑”过。


很多新同学都会有个疑问:

明明是 JDK 自带的类,
为什么老项目里一堆 Date,
但新项目却几乎看不到它了?


答案很简单一句话:

它太老了,老到不适合现代开发。


今天我们就用最直观的代码 + 最真实的坑,把这个“Java 的老古董”一次性讲清楚。



-01-

一个“活化石”级别的类

java.util.Date诞生于 Java 1.0(1996 年)。

那一年:

  • Java 还没泛型
  • 还没注解
  • 甚至连集合框架都不完整

你现在看到的 Date,本质是 30 年前的设计产物

Date date = newDate();System.out.println(date);


输出:

MonSep2209:50:24CST2025


看起来是不是很“正常”?
坑,正是从这里开始的。


java.util.Date 为什么被嫌弃?



-02-

Date 的三大“反人类”设计缺陷

1. API 设计:

Date date = newDate();System.out.println("当前年月日:" + LocalDate.now());System.out.println(date.getYear());System.out.println(date.getMonth());

输出:

当前年月日:2025-09-221258


问题来了:

  • getYear() 返回 125?
  • getMonth() 返回 8?

原因是:

  • 年份:从 1900 年开始算
  • 月份:从 0 开始(0 = 一月)


2. 可变对象:

Date date = newDate(2025 - 1900, 8, 22);System.out.println("原定日期: " + date);// 某个地方悄悄改了它date.setYear(2026 - 1900);System.out.println("修改后的日期: " + date);

输出:

原定日期: Mon Sep 22 00:00:00 CST 2025修改后的日期: Tue Sep 22 00:00:00 CST 2026


在多线程环境下:

  • 谁改了?
  • 什么时候改的?
  • 为什么变了?

debug 到秃头都找不到[哭]


3. 时区语义混乱

Date now = newDate();System.out.println(now);

你看到的是:

  • 系统默认时区的展示结果

但 Date 本身:

  • 只存一个毫秒时间戳
  • 根本不关心时区

展示和真实语义是分裂的,非常容易踩坑。



java.util.Date 为什么被嫌弃?




-03-

一个真实业务场景:算天数差

用 Date算两个日期差几天,你只能这么干:

Date date1 = newDate(125, 8, 22);  // 2025-09-22Date date2 = newDate(125, 9, 22);  // 2025-10-22long diff = date2.getTime() - date1.getTime();long days = diff / (1000 * 60 * 60 * 24);System.out.println("相差天数: " + days);

问题是:

  • 可读性差
  • 全是魔法数字
  • 时区 / 夏令时一变就翻车



java.util.Date 为什么被嫌弃?



-04-

最后的最后

替代方案:Java 8 时间 API(java.time)

Java 8 之后,官方已经给出了“正确答案”

1. API 清晰到像自然语言

LocalDate date = LocalDate.of(2025, 9, 22);System.out.println(date);
LocalDateTime now = LocalDateTime.now();
ZonedDateTime shanghai =ZonedDateTime.now(ZoneId.of("Asia/Shanghai"));


2. 不可变对象,天生线程安全

LocalDate appointment = LocalDate.of(2025, 9, 22);LocalDate newDate = appointment.plusDays(30);
  • 原对象不变
  • 返回新对象
  • 并发场景天然安全


3. 时间计算一行搞定

long days = ChronoUnit.DAYS.between(    LocalDate.of(2025, 9, 22),    LocalDate.of(2025, 10, 22));

这才是 “业务代码”该有的样子


4. 时区是显式的,而不是“猜的”

ZonedDateTime shanghai=    ZonedDateTime.now(ZoneId.of("Asia/Shanghai"));ZonedDateTime newYork=    shanghai.withZoneSameInstant(        ZoneId.of("America/New_York")    );
java.util.Date 为什么被嫌弃?



老项目怎么办?

不用你“一刀切重构”

推荐做法:

  • 新代码:一律用 java.time
  • 旧代码交互:只在边界转换
public static LocalDate toLocalDate(Date date) {if (date == null) {return null;    }return date.toInstant()               .atZone(ZoneId.systemDefault())               .toLocalDate();}
publicstatic LocalDateTime toLocalDateTime(Date date) {if (date == null) {return null;    }return date.toInstant()               .atZone(ZoneId.systemDefault())               .toLocalDateTime();}
java.util.Date 为什么被嫌弃?


(面试直接背)

java.util.Date 是历史产物,
可变、反直觉、时区混乱、不适合现代并发系统

Java 8 之后,java.time 才是唯一正确选择


如果你在项目里还大量看到 Date,

那不是你的错——
但你有责任在新代码里终结它

java.util.Date 为什么被嫌弃?





-05-

粉丝福利




点点关注,送你互联网大厂面试题库,如果你正在找工作,又或者刚准备换工作。可以仔细阅读一下,或许对你有所帮助!


java.util.Date 为什么被嫌弃?

java.util.Date 为什么被嫌弃?

java.util.Date 为什么被嫌弃?


查看详情:https://www.toutiao.com/article/7592181900400149007
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

QQ|手机版|小黑屋|梦想之都-俊月星空 ( 粤ICP备18056059号 )|网站地图

GMT+8, 2026-1-24 14:54 , Processed in 0.042648 second(s), 17 queries .

Powered by Mxzdjyxk! X3.5

© 2001-2025 Discuz! Team.

返回顶部