沉默是金,总会发光 大家好,我是沉默
如果你是一名 Java 开发者,java.util.Date这个类你一定见过。
甚至可以说—— 你没主动用过,也一定被它“坑”过。
很多新同学都会有个疑问: 明明是 JDK 自带的类, 为什么老项目里一堆 Date, 但新项目却几乎看不到它了?
答案很简单一句话: 它太老了,老到不适合现代开发。
今天我们就用最直观的代码 + 最真实的坑,把这个“Java 的老古董”一次性讲清楚。
-01- 一个“活化石”级别的类 java.util.Date诞生于 Java 1.0(1996 年)。那一年: 你现在看到的 Date,本质是 30 年前的设计产物。 Date date = newDate();System.out.println(date);
输出: MonSep2209:50:24CST2025
看起来是不是很“正常”? 坑,正是从这里开始的。
-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 本身: 展示和真实语义是分裂的,非常容易踩坑。
-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);
问题是:
-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.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 8 之后,java.time 才是唯一正确选择。
如果你在项目里还大量看到 Date, 那不是你的错—— 但你有责任在新代码里终结它。
-05- 粉丝福利
点点关注,送你互联网大厂面试题库,如果你正在找工作,又或者刚准备换工作。可以仔细阅读一下,或许对你有所帮助!
查看详情:https://www.toutiao.com/article/7592181900400149007 免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作! |