java date类型做加法发现的问题

本文介绍了一种在Java中为日期增加天数的方法,并通过一个具体案例揭示了使用整型变量进行时间计算可能导致的溢出问题。作者最初采用将日期转换为毫秒数再进行加法运算的方式,但在尝试增加25天以上时遇到了日期回退的异常现象。经过排查,最终发现问题是由于整型变量乘法运算超过了其最大表示范围。

oracle里面有个add_months函数可以对某个日期做加多少个月份的操作,对日期做加法更简单只需用+号就可以了。可是在java里面要实现日期加多少天,只能自己写个方法了。

一种途径是:

1 得到基准日期对应的毫秒数 a = date.getTime()

2 得到要加的天数的毫秒数 b = n天*每天毫秒数(t=24*60*60*1000)

3 c = a+b,然后返回new Date(c);

我一直采用这种方法,直到今天忽然发现不对劲。n=24还没问题,当n>=25时结果就不对劲变小了。

这实在太奇怪了,为什么呢?难道是jdk的bug?

几经测试,终于发现问题所在:

原来我定义 t=24*60*60*1000时前面的类型修饰符是int,这样t*24的时候没问题,t*25时就超过int的最大范围变成负数了,于是a+b的结果就变小了,从而最后相加了n天后的日期反而比基准日期小了。

### 如何在 Java 中对 `Date` 类型执行日期减操作 对于 `Date` 类型的日期减操作,在现代 Java 开发中推荐使用 `java.time` 包下的类,如 `LocalDateTime`, `ZonedDateTime` 或者其他更现代化的时间 API。然而,如果项目需求或环境限制使得必须采用旧版的方式处理,则可以借助于 `Calendar` 类完成此功能。 #### 使用 Calendar 进行 Date减操作 通过 `Calendar` 实现对 `Date` 对象的操作主要依赖几个核心方法: - 获取当前日历实例:`getInstance()` 方法用于创建一个新的 GregorianCalendar 子类对象并初始化为当前时刻。 - 设置时间戳:利用 `setTime(Date date)` 将给定的 `Date` 赋值到该实例内以便后续修改。 - 执行增减计算:调用 `add(int field, int amount)` 函数改变特定字段(例如年、月、天等),其中正负参数决定了增还是减少相应的单位数量。 - 提取更新后的日期:最后再通过 `getTime()` 返回被调整过的新 `Date` 值[^3]。 下面是具体实现的例子: ```java import java.text.SimpleDateFormat; import java.util.Date; import java.util.Calendar; public class DateAddExample { public static void main(String[] args) throws Exception { SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); // 创建一个表示现在时间的对象 Date currentDate = new Date(); System.out.println("原始时间为:" + sdf.format(currentDate)); // 初始化 calendar 并设置其时间为 current_date Calendar cal = Calendar.getInstance(); cal.setTime(currentDate); // 向当前时间添一天(-1 表示前一天) cal.add(Calendar.DAY_OF_MONTH, -1); Date previousDay = cal.getTime(); System.out.println("前一天时间为:" + sdf.format(previousDay)); // 添两小时(正值代表未来) cal.add(Calendar.HOUR_OF_DAY, 2); Date twoHoursLater = cal.getTime(); System.out.println("两个小时之后的时间为:" + sdf.format(twoHoursLater)); } } ``` 这段程序展示了怎样基于现有的 `Date` 变量来进行简单的加法和减法规则应用,并打印出每次变换的结果以供验证。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值