在Java中Date类有哪些局限性_Java旧日期类问题解析
发布时间 - 2026-01-25 00:00:00 点击率:次Date类本质是UTC毫秒计数器,toString()伪装成本地时间;其可变性、0基月份、线程不安全及设计缺陷使其被java.time替代。
Java 的 Date 类不是“过时了”,而是从设计第一天起就和现代时间模型不兼容——它名义上叫 Date,实际是个带误导性 toString() 的毫秒计数器。
为什么 new Date() 打印出来像本地时间,却不是本地时间?
Date 内部只存一个 long 值:自 1970-01-01 00:00:00 UTC 起的毫秒数(即 Instant)。但它的 toString() 方法偷偷调用系统默认时区格式化输出,造成“它含时区”的错觉。
- 你写
new Date(),得到的是一个 UTC 时间点,不是“北京时间”或“纽约时间” - 跨时区服务中,若把
Date当作“无时区时间”传给前端或数据库,很可能在新加坡服务器上存了中国用户提交的“2026-01-19 10:00:00”,结果查出来变成 “2026-01-19 02:00:00”(因误按 UTC 解析) - 真正需要“本地日期+时间”语义时,该用
LocalDateTime;需要明确时区转换时,该用ZonedDateTime或Instant
月份从 0 开始、年份要减 1900:不是 bug,是历史包袱
这是最常踩的坑——date.setMonth(1) 不是设成 1 月,而是 2 月;date.setYear(126) 表示的是 2026 年(1900 + 126),但如果你手抖写了 setYear(2026),那恭喜,你创建了一个 3926 年的日期。
- 所有
getXXX()/setXXX()方法(如getMonth()、getDate()、getHours())都已标为@Deprecated,编译器会警告,运行时也可能出错 - 这种偏移不是 Java 特有,而是照搬 C 语言
struct tm,但 Java 早已不需要向后兼容这种底层细节 - 替代方案:用
LocalDateTime.of(2026, 1, 19, 18, 42),参数含义一目了然,且编译期就能校验范围
可变性 + 线程不安全 = 隐形炸弹
Date 是可变对象,任何持有引用的地方都能调用 setTime()、setHours() 直接改掉原始值。这在多线程、集合键、DTO 传递等场景下极易引发数据污染。
- 把它放进
HashSet当 key,之后又调用setTime(),哈希码改变,对象再也找不回来 - Spring MVC 接收 JSON 时若用
Date字段,反序列化后可能被拦截器或业务逻辑意外修改,下游拿到的是被篡改的时间 -
java.time全家桶(LocalDateTime、Instant、ZonedDateTime)都是final+ 不可变,赋值即拷贝,天然线程安全
SimpleDateFormat 和 Calendar:补丁套补丁,越补越危险
想格式化?得配 SimpleDateFormat;想加一天?得转 Calendar;想解析字符串?还得靠它——而这两个类全是线程不安全的重灾区。
-
SimpleDateFormat内部维护Calendar实例和缓冲区,多线程共享静态实例时,常见输出 “2026-13-19” 或直接抛NumberFormatException -
Calendar的get()/set()同样沿用 0 基月份,且每次操作都要新建实例或重置状态,性能差、易遗漏 - 正确做法:
DateTimeFormatter.ISO_LOCAL_DATE_TIME是static final、线程安全;日期计算用localDateTime.plusDays(1),链式调用,不可变返回
迁移不是简单替换字段类型,关键是厘清语义:数据库里是 DATETIME(无时区)?那就换 LocalDateTime;是 TIMESTAMP WITH TIME ZONE?必须用 OffsetDateTime 或 ZonedDateTi;对外提供时间戳接口?统一走 
Instant.now().toEpochMilli()。混淆这三者,比继续用 Date 更危险。
# java
# js
# 前端
# json
# spring mvc
# 格式化输出
# 为什么
相关栏目:
【
网站优化151355 】
【
网络推广146373 】
【
网络技术251813 】
【
AI营销90571 】
相关推荐:
如何用wdcp快速搭建高效网站?
图册素材网站设计制作软件,图册的导出方式有几种?
EditPlus 正则表达式 实战(3)
linux写shell需要注意的问题(必看)
JavaScript如何操作视频_媒体API怎么控制播放
rsync同步时出现rsync: failed to set times on “xxxx”: Operation not permitted
如何在阿里云域名上完成建站全流程?
如何构建满足综合性能需求的优质建站方案?
百度输入法ai组件怎么删除 百度输入法ai组件移除工具
Laravel事件监听器怎么写_Laravel Event和Listener使用教程
如何在VPS电脑上快速搭建网站?
5种Android数据存储方式汇总
头像制作网站在线观看,除了站酷,还有哪些比较好的设计网站?
如何在 Telegram Web View(iOS)中防止键盘遮挡底部输入框
Laravel如何处理表单验证?(Requests代码示例)
如何制作一个表白网站视频,关于勇敢表白的小标题?
焦点电影公司作品,电影焦点结局是什么?
千库网官网入口推荐 千库网设计创意平台入口
高性能网站服务器部署指南:稳定运行与安全配置优化方案
如何实现javascript表单验证_正则表达式有哪些实用技巧
Python高阶函数应用_函数作为参数说明【指导】
Laravel如何使用Seeder填充数据_Laravel模型工厂Factory批量生成测试数据【方法】
Laravel怎么实现搜索功能_Laravel使用Eloquent实现模糊查询与多条件搜索【实例】
Laravel如何使用Vite进行前端资源打包?(配置示例)
Win11应用商店下载慢怎么办 Win11更改DNS提速下载【修复】
Laravel怎么集成Log日志记录_Laravel单文件与每日日志配置及自定义通道【详解】
如何破解联通资金短缺导致的基站建设难题?
C++用Dijkstra(迪杰斯特拉)算法求最短路径
Win10如何卸载预装Edge扩展_Win10卸载Edge扩展教程【方法】
新三国志曹操传主线渭水交兵攻略
如何自定义建站之星网站的导航菜单样式?
Laravel如何自定义错误页面(404, 500)?(代码示例)
Python面向对象测试方法_mock解析【教程】
php打包exe后无法访问网络共享_共享权限设置方法【教程】
PythonWeb开发入门教程_Flask快速构建Web应用
微信小程序制作网站有哪些,微信小程序需要做网站吗?
阿里云网站搭建费用解析:服务器价格与建站成本优化指南
Javascript中的事件循环是如何工作的_如何利用Javascript事件循环优化异步代码?
通义万相免费版怎么用_通义万相免费版使用方法详细指南【教程】
软银砸40亿美元收购DigitalBridge 强化AI资料中心布局
laravel怎么用DB facade执行原生SQL查询_laravel DB facade原生SQL执行方法
详解jQuery中基本的动画方法
laravel怎么通过契约(Contracts)编程_laravel契约(Contracts)编程方法
如何快速搭建二级域名独立网站?
微信小程序 闭包写法详细介绍
网站制作公司哪里好做,成都网站制作公司哪家做得比较好,更正规?
Laravel Pest测试框架怎么用_从PHPUnit转向Pest的Laravel测试教程
JS弹性运动实现方法分析
什么是JavaScript解构赋值_解构赋值有哪些实用技巧
Android GridView 滑动条设置一直显示状态(推荐)

