0

0

Java中的Date和Calendar类怎么用_传统日期时间API的基础与常见坑点

P粉602998670

P粉602998670

发布时间:2026-03-13 05:25:29

|

387人浏览过

|

来源于php中文网

原创

Date构造器年份参数是距1900年的偏移量,如new Date(2024,0,1)实际为2924年;月份从0开始;该构造器已弃用,应改用LocalDateTime或Calendar;SimpleDateFormat非线程安全;Calendar.DAY_OF_WEEK与日常认知不一致,建议用LocalDateTime.getDayOfWeek();set()惰性设置,add()立即计算;时区易出错,推荐用toInstant()或Instant过渡。

java中的date和calendar类怎么用_传统日期时间api的基础与常见坑点

Date 构造时间时,年份参数是「1900年起始偏移量」

这是最常踩的坑:传 new Date(2024, 0, 1) 得到的不是 2024 年 1 月 1 日,而是 2025 年 1 月 1 日(因为年份按「距 1900 年的差值」算,2024 − 1900 = 1024,所以实际是 1024 + 1900 = 2924 年)。更糟的是,月份从 0 开始,0 表示一月,11 表示十二月。

  • 永远别用带参数的 Date(int, int, int) 构造器 —— 它在 Java 9+ 已被标记为 @Deprecated,且语义反直觉
  • 想从年月日构造时间,改用 Calendar 设置再调 calendar.getTime(),或直接升级到 LocalDateTime.of(2024, 1, 1, 0, 0)
  • 如果必须解析字符串,用 SimpleDateFormat,但注意它不是线程安全的 —— 多线程下必须每个线程 new 一个实例,或用 ThreadLocal 包装

Calendar.get(Calendar.DAY_OF_WEEK) 返回的数字和日常认知不一致

它返回的是 Calendar.SUNDAY = 1、Calendar.MONDAY = 2 … Calendar.SATURDAY = 7。这和 ISO 8601(周一为第一天)或很多数据库(如 MySQL 的 WEEKDAY() 返回 0=周一)都对不上。

  • 不要直接拿返回值做「周几中文映射」,先确认你用的 Calendar 实例的 getFirstDayOfWeek() 是什么(不同 Locale 可能不同)
  • 跨系统对接时,建议统一转成 ISO 标准:用 calendar.get(Calendar.DAY_OF_WEEK) - calendar.getFirstDayOfWeek() + 1 再模 7 调整
  • 更简单的方式:用 LocalDateTime.getDayOfWeek().getValue()(周一=1,周日=7),语义清晰且不可变

Calendarset()add() 行为差异极大

set() 是「惰性设置」:只记下字段值,不立即计算时间戳;而 add() 会立刻触发重计算,并处理进位/借位(比如给 1 月 31 日加一个月,结果是 2 月 28 日或 29 日)。

  • 连续调用多次 set() 后直接 getTime(),可能因字段冲突导致意外结果(例如先设 DAY_OF_MONTH = 31,再设 MONTH = 1(二月),最终时间可能是 3 月 3 日)
  • 需要精确增减日期时,无条件选 add();仅需覆盖单个字段且确定其他字段无冲突时,才用 set()
  • 如果用 set() 后还要读其他字段(如 get(Calendar.WEEK_OF_YEAR)),务必在读之前调一次 calendar.getTime()calendar.complete() 强制刷新

DateCalendarInstant 时,时区容易被忽略

Date 本质是毫秒数(UTC 时间轴上的点),但 Calendar 默认绑定 JVM 本地时区。直接 calendar.getTime().toInstant() 看似没问题,可一旦 Calendar 是用非默认时区构造的(比如 Calendar.getInstance(TimeZone.getTimeZone("GMT"))),结果就可能错。

AI小聚
AI小聚

一站式多功能AIGC创作平台,支持AI绘画、AI视频、AI聊天、AI音乐

下载

立即学习Java免费学习笔记(深入)”;

  • 最安全的转换路径:用 calendar.toInstant()(Java 8+),它明确基于 Calendar 自身的时区上下文
  • 如果只有 Date,它转 Instant 是安全的(date.toInstant()),但反过来 instant.toEpochMilli() 再塞进 Date 构造器,会丢失纳秒精度(Date 只支持毫秒)
  • 所有涉及「显示给用户看的时间」,千万别只靠 Date.toString() —— 它内部用本地时区格式化,同一毫秒数在不同时区机器上输出完全不同

这些类的设计初衷是适配上世纪 90 年代的时区和历法需求,现在看处处是隐式状态和时区陷阱。哪怕只是临时兼容老代码,也建议把解析、计算、展示三阶段严格拆开,中间统一用 InstantZonedDateTime 过渡。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

WorkBuddy
WorkBuddy

腾讯云推出的AI原生桌面智能体工作台

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
mysql修改数据表名
mysql修改数据表名

MySQL修改数据表:1、首先查看数据库中所有的表,代码为:‘SHOW TABLES;’;2、修改表名,代码为:‘ALTER TABLE 旧表名 RENAME [TO] 新表名;’。php中文网还提供MySQL的相关下载、相关课程等内容,供大家免费下载使用。

686

2023.06.20

MySQL创建存储过程
MySQL创建存储过程

存储程序可以分为存储过程和函数,MySQL中创建存储过程和函数使用的语句分别为CREATE PROCEDURE和CREATE FUNCTION。使用CALL语句调用存储过程智能用输出变量返回值。函数可以从语句外调用(通过引用函数名),也能返回标量值。存储过程也可以调用其他存储过程。php中文网还提供MySQL创建存储过程的相关下载、相关课程等内容,供大家免费下载使用。

513

2023.06.21

mongodb和mysql的区别
mongodb和mysql的区别

mongodb和mysql的区别:1、数据模型;2、查询语言;3、扩展性和性能;4、可靠性。本专题为大家提供mongodb和mysql的区别的相关的文章、下载、课程内容,供大家免费下载体验。

287

2023.07.18

mysql密码忘了怎么查看
mysql密码忘了怎么查看

MySQL是一个关系型数据库管理系统,由瑞典MySQL AB 公司开发,属于 Oracle 旗下产品。MySQL 是最流行的关系型数据库管理系统之一,在 WEB 应用方面,MySQL是最好的 RDBMS 应用软件之一。那么mysql密码忘了怎么办呢?php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

519

2023.07.19

mysql创建数据库
mysql创建数据库

MySQL是一个关系型数据库管理系统,由瑞典MySQL AB 公司开发,属于 Oracle 旗下产品。MySQL 是最流行的关系型数据库管理系统之一,在 WEB 应用方面,MySQL是最好的 RDBMS 应用软件之一。那么mysql怎么创建数据库呢?php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

267

2023.07.25

mysql默认事务隔离级别
mysql默认事务隔离级别

MySQL是一种广泛使用的关系型数据库管理系统,它支持事务处理。事务是一组数据库操作,它们作为一个逻辑单元被一起执行。为了保证事务的一致性和隔离性,MySQL提供了不同的事务隔离级别。php中文网给大家带来了相关的教程以及文章欢迎大家前来学习阅读。

392

2023.08.08

sqlserver和mysql区别
sqlserver和mysql区别

SQL Server和MySQL是两种广泛使用的关系型数据库管理系统。它们具有相似的功能和用途,但在某些方面存在一些显著的区别。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

542

2023.08.11

mysql忘记密码
mysql忘记密码

MySQL是一种关系型数据库管理系统,关系数据库将数据保存在不同的表中,而不是将所有数据放在一个大仓库内,这样就增加了速度并提高了灵活性。那么忘记mysql密码我们该怎么解决呢?php中文网给大家带来了相关的教程以及其他关于mysql的文章,欢迎大家前来学习阅读。

668

2023.08.14

Python异步编程与Asyncio高并发应用实践
Python异步编程与Asyncio高并发应用实践

本专题围绕 Python 异步编程模型展开,深入讲解 Asyncio 框架的核心原理与应用实践。内容包括事件循环机制、协程任务调度、异步 IO 处理以及并发任务管理策略。通过构建高并发网络请求与异步数据处理案例,帮助开发者掌握 Python 在高并发场景中的高效开发方法,并提升系统资源利用率与整体运行性能。

37

2026.03.12

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Kotlin 教程
Kotlin 教程

共23课时 | 4.3万人学习

C# 教程
C# 教程

共94课时 | 11.2万人学习

Java 教程
Java 教程

共578课时 | 81万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号