在Java里Calendar类如何进行日期计算_Java时间处理方式说明

发布时间 - 2026-01-30 00:00:00    点击率:
Calendar.add()需配合setLenient(false)防意外进位,操作月份用Calendar.MONTH而非数字1,获取当月天数优先用getActualMaximum(),多线程下须每次newInstance或clone,Calendar虽过时但在跨时区、历法细节等场景仍不可替代。

Calendar.add() 是日期计算的核心方法,但必须配合 setLenient(false) 防止意外进位

直接调用 add() 看似简单,但默认的宽松模式(lenient)会让 2025-02-30 变成 2025-03-02,而不是抛异常。这在金融、考勤等强校验场景极易埋雷。

  • 务必在创建实例后立即调用 calendar.setLenient(false)
  • add() 修改的是内部字段值,不触发即时重算;如需立刻生效并校验,后续要调用 calendar.getTime()calendar.get(Calendar.DAY_OF_MONTH)
  • 对月份操作要特别注意:1 月对应 Calendar.JANUARY = 0,所以加 1 个月应传 Calendar.MONTH,而非硬写 1

getActualMaximum() 比直接写死 31 更安全地获取当月天数

calendar.getActualMaximum(Calendar.DAY_OF_MONTH) 获取当前 Calendar 实例所在月份的实

际最大天数,比判断是否闰年再分支处理更简洁可靠。

  • 它自动考虑平年/闰年、大小月、甚至农历相关 Calendar 子类(如 JapaneseCalendar)
  • 不能用于任意日期构造——必须先用 set()setTime() 定位到目标年月,再调用
  • 例如:想算 2025 年 2 月有多少天,得先 calendar.set(2025, Calendar.FEBRUARY, 1),再调 getActualMaximum()

Calendar.getInstance() 返回的是可变对象,多线程下必须每次 new 或 clone

静态方法 Calendar.getInstance() 返回的实例不是线程安全的。多个线程共用同一个实例调用 set()add(),结果不可预测。

  • 推荐做法:每次需要时都调用 Calendar.getInstance(),不要缓存复用
  • 若性能敏感且必须复用,用 calendar.clone() 获得副本(返回类型是 Object,需强制转型)
  • 避免用 static final Calendar —— 这是典型的线程安全陷阱

Calendar 已过时,但 LocalDate.plusDays() 等 API 无法替代所有场景

Java 8 的 LocalDate 确实更直观,但它没有内置时区偏移计算、也没有类似 getLeastMaximum() 这种细粒度日历逻辑支持。

  • 涉及跨时区时间推算(比如“北京时间上午9点 + 24小时”是否仍为上午9点)、或需兼容旧系统返回的 java.util.Date 时,Calendar 仍是绕不开的中间层
  • Calendar.toInstant()Instant.atZone() 是桥接新旧 API 的关键组合
  • 别试图把所有 Calendar 逻辑强行改造成 LocalDate —— 有些业务规则本身就依赖 GregorianCalendar 的闰秒/历法细节
真正麻烦的不是怎么加减天数,而是搞清你到底在跟哪个历法系统打交道:Gregorian?Julian?还是某个自定义 Calendar 子类。没确认清楚就调 add(),结果可能连自己都解释不了。


# java  # go  # win  # 金融  # lmax  # Static  # Object  # 子类  # date  # Calendar  # 线程  # 多线程  # 对象  # 的是  # 当月  # 而非  # 复用  # 这是  # 上午  # 中间层  # 多个 


相关栏目: 【 网站优化151355 】 【 网络推广146373 】 【 网络技术251813 】 【 AI营销90571


相关推荐: 七夕网站制作视频,七夕大促活动怎么报名?  如何快速搭建虚拟主机网站?新手必看指南  高防服务器租用如何选择配置与防御等级?  如何挑选最适合建站的高性能VPS主机?  制作企业网站建设方案,怎样建设一个公司网站?  Laravel如何理解并使用服务容器(Service Container)_Laravel依赖注入与容器绑定说明  Laravel如何从数据库删除数据_Laravel destroy和delete方法区别  详解vue.js组件化开发实践  Laravel的HTTP客户端怎么用_Laravel HTTP Client发起API请求教程  Laravel如何设置定时任务(Cron Job)_Laravel调度器与任务计划配置  谷歌浏览器如何更改浏览器主题 Google Chrome主题设置教程  如何自己制作一个网站链接,如何制作一个企业网站,建设网站的基本步骤有哪些?  微信小程序 闭包写法详细介绍  晋江文学城电脑版官网 晋江文学城网页版直接进入  Laravel中DTO是什么概念_在Laravel项目中使用数据传输对象(DTO)  Laravel中间件如何使用_Laravel自定义中间件实现权限控制  node.js报错:Cannot find module 'ejs'的解决办法  Laravel怎么实现验证码(Captcha)功能  Laravel的契約(Contracts)是什么_深入理解Laravel Contracts与依赖倒置  教你用AI润色文章,让你的文字表达更专业  北京网站制作公司哪家好一点,北京租房网站有哪些?  如何用免费手机建站系统零基础打造专业网站?  如何基于云服务器快速搭建网站及云盘系统?  奇安信“盘古石”团队突破 iOS 26.1 提权  Laravel Seeder怎么填充数据_Laravel数据库填充器的使用方法与技巧  iOS UIView常见属性方法小结  Laravel如何升级到最新版本?(升级指南和步骤)  百度输入法ai面板怎么关 百度输入法ai面板隐藏技巧  Laravel队列由Redis驱动怎么配置_Laravel Redis队列使用教程  Laravel Facade的原理是什么_深入理解Laravel门面及其工作机制  在线制作视频的网站有哪些,电脑如何制作视频短片?  香港服务器租用每月最低只需15元?  IOS倒计时设置UIButton标题title的抖动问题  phpredis提高消息队列的实时性方法(推荐)  如何快速生成高效建站系统源代码?  微博html5版本怎么弄发超话_超话进入入口及发帖格式要求【教程】  如何使用 jQuery 正确渲染 Instagram 风格的标签列表  详解免费开源的.NET多类型文件解压缩组件SharpZipLib(.NET组件介绍之七)  Laravel安装步骤详细教程_Laravel环境搭建指南  儿童网站界面设计图片,中国少年儿童教育网站-怎么去注册?  Laravel怎么使用Intervention Image库处理图片上传和缩放  Laravel如何与Docker(Sail)协同开发?(环境搭建教程)  Laravel N+1查询问题如何解决_Eloquent预加载(Eager Loading)优化数据库查询  韩国服务器如何优化跨境访问实现高效连接?  Laravel如何实现密码重置功能_Laravel密码找回与重置流程  米侠浏览器网页图片不显示怎么办 米侠图片加载修复  北京的网站制作公司有哪些,哪个视频网站最好?  JS实现鼠标移上去显示图片或微信二维码  Angular 表单中正确绑定输入值以确保提交与验证正常工作  黑客如何通过漏洞一步步攻陷网站服务器?