新旧api设计意图对比凸显java.time的语义清晰与不可变性:date/calendar因月份从0起、年份减1900等历史包袱违背直觉,且职责混乱、线程不安全;而localdate、localtime等各司其职,instant表utc时间戳,zoneddatetime处理时区与夏令时,plusdays等操作天然线程安全并自动处理边界。

直接对比新旧 API 的设计意图和实际表现,比罗列知识点更能让面试官看到你的理解深度。重点不是“会用”,而是“知道为什么这么设计”。
先说清楚“为什么淘汰 Date 和 Calendar”
别只说“线程不安全”“API 难用”,要讲清背后的设计缺陷:
- 月份从 0 开始(1 月是 0)、年份要减 1900 —— 这是历史包袱,违背直觉,容易埋坑;
- Date 本质是毫秒时间戳,却常被当“日期”用,导致时区混淆、格式化出错;
- Calendar 是可变对象,一次 set() 就改掉整个状态,多线程共享时极易出错,且无法回滚;
- 没有清晰的语义分离:一个类既要管日期、又要管时间、还要处理时区,职责过重。
用类比讲清 java.time 核心类的分工
面试时一说就懂,不靠背定义:
- LocalDate:身份证上的生日 —— 只有年月日,不含时间,不涉及时区;
- LocalTime:你手表显示的时间 —— 只有时分秒,没有日期;
- LocalDateTime:数据库里的 datetime 字段 —— 日期+时间,但仍是“本地”概念,无时区含义;
- ZonedDateTime:跨国会议邀约时间 —— 带时区信息,能正确处理夏令时切换;
- Instant:系统日志里的精确时间戳 —— 全球统一的 UTC 时间点,适合计算耗时、排序、存档。
操作题别光写代码,带出设计逻辑
比如被问“怎么给今天加 30 天”,不要只答 LocalDate.now().plusDays(30):
- 强调不可变性:它不会修改原对象,而是返回新实例,所以天然线程安全;
- 说明语义清晰:
plusDays比calendar.add(Calendar.DAY_OF_MONTH, 30)更接近自然语言; - 顺带提边界:加 30 天后若落在 2 月 30 日,LocalDate 会自动归到 3 月 2 日或 3 日(取决于是否闰年),无需手动处理;
- 如果涉及跨月/跨年计算,可补充
Period.between()用于表达“相差多少年、多少月、多少天”这类业务语义。
格式化与解析务必点破关键细节
这是高频踩坑点,提前暴露判断力:
- 用
DateTimeFormatter.ofPattern("yyyy-MM-dd"),不用"YYYY-MM-DD"—— 大写YYYY是“周基准年”,和yyyy在年末年初可能不一致; - 小写
dd是“月中的第几天”,大写DD是“年中的第几天”,写错会导致 2026-10-09 变成 “2026-10-282”; -
DateTimeFormatter是线程安全的,可复用;而老版SimpleDateFormat必须每次 new 或用 ThreadLocal 包装。
大量免费API接口:立即使用
涵盖生活服务API、金融科技API、企业工商API、等相关的API接口服务。免费API接口可安全、合规地连接上下游,为数据API应用能力赋能!











