max日期最大值为0_获取指定日期和它之前几天,之间的所有日期?千万不要踩了这个大坑!...

今天在开会谈需求的时候,遇到了这么一个需求:要求动态的获得当前日期往前推30天,这之间所有天数的数据之和。

首先会想到的,肯定是Java里处理日期的几个类,常用的有三个:Date,SimpleDateFormat,和Calendar。将他们三个类组合运用,基本上就能满足大部分项目中,对于日期处理的需求。

其次,这个项目的数据,在数据库里存的日期是yyyy-MM-dd格式的。所以我需要获取这30天的满足这种格式的所有字符串日期,然后用sql语句查出对应的数据。

稍加思考,对于这类需求的算法思路就是:

1.将指定日期通过SimpleDateFormat转换成Date类型。

2.通过Date的getTime()方法,获取当前的毫秒数。

3.将当前日期获得的毫秒数-往前推的第几天*每一天的毫秒数,就得到了往前推的第几天的毫秒数。

4.将获取的之前天数的毫秒数,通过SimpleDateFormat转换成需要的时间格式,就获得了那一天的时间字符串。

5.循环拿着获取的每一个时间字符串通过sql获取对应的数据。

对于日期部分的需求,用代码来表示就是:

SimpleDateFormat simpleDateFormat=new SimpleDateFormat("yyyy-MM-dd");
 Date date= simpleDateFormat.parse("2019-10-10"); //填入指定日期
 DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
 for (int i = 0; i < N; i++) {
      String time = df.format(date.getTime() - i * 24 * 60 * 60 * 1000);
      System.out.println(time);
      }

如果是贴合项目的需求,不用指定日期而用当前日期,就可以简化为:

 DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
 for (int i = 0; i < N; i++) {
      String time = df.format(System.currentTimeMillis()- i * 24 * 60 * 60 * 1000);
      System.out.println(time);
      }

这里的N,表示往前推多少天。如果要往前推15天,N就是15。

得到的结果,就是最终转换成了指定格式的,每一天的日期

当N==15的时候,会得到下面的结果:

2019-10-10, 2019-10-09, 2019-10-08, 2019-10-07, 2019-10-06, 2019-10-05, 2019-10-04, 2019-10-03, 2019-10-02, 2019-10-01, 2019-09-30, 2019-09-29, 2019-09-28, 2019-09-27, 2019-09-26

到这里,日期的需求就已经解决了,也达到了预想中的结果。

然后我将N改为30,顺便打印一下结果,Bug出现了,而且很大。

先看看结果是怎么样的吧。

当N==30的时候,结果为:

2019-10-10, 2019-10-09, 2019-10-08, 2019-10-07, 2019-10-06, 2019-10-05, 2019-10-04, 2019-10-03, 2019-10-02, 2019-10-01, 2019-09-30, 2019-09-29, 2019-09-28, 2019-09-27, 2019-09-26, 2019-09-25, 2019-09-24, 2019-09-23, 2019-09-22, 2019-09-21, 2019-09-20, 2019-09-19, 2019-09-18, 2019-09-17, 2019-09-16, 2019-11-03, 2019-11-02, 2019-11-01, 2019-10-31, 2019-10-30

前面还很正常,到了2019-09-16之后,日期就乱了,日期跳到了2019-11-03号了。

查了很多帖子,看了Java的Api,都没有发现问题出现在哪里。只有通过自Debug慢慢的找原因了。

通过不断的尝试,我发现25是一个临界点,当N超过25的时候,日期就会出现错误。

当N==25时,结果是正常的:

2019-10-10, 2019-10-09, 2019-10-08, 2019-10-07, 2019-10-06, 2019-10-05, 2019-10-04, 2019-10-03, 2019-10-02, 2019-10-01, 2019-09-30, 2019-09-29, 2019-09-28, 2019-09-27, 2019-09-26, 2019-09-25, 2019-09-24, 2019-09-23, 2019-09-22, 2019-09-21, 2019-09-20, 2019-09-19, 2019-09-18, 2019-09-17, 2019-09-16

当N==26时,结果就乱了:

2019-10-10, 2019-10-09, 2019-10-08, 2019-10-07, 2019-10-06, 2019-10-05, 2019-10-04, 2019-10-03, 2019-10-02, 2019-10-01, 2019-09-30, 2019-09-29, 2019-09-28, 2019-09-27, 2019-09-26, 2019-09-25, 2019-09-24, 2019-09-23, 2019-09-22, 2019-09-21, 2019-09-20, 2019-09-19, 2019-09-18, 2019-09-17, 2019-09-16, 2019-11-03

什么原因呢?百思不得其解。。。

去上了个厕所,有头绪了。

问题是不是出在计算毫秒的公式上?:

System.currentTimeMillis()- i * 24 * 60 * 60 * 1000

当N等于25的时候,i的最大值是24。

24* 24 * 60 * 60 * 1000=2,073,600,000

当N等于26的时候,i的最大值是25。

25* 24 * 60 * 60 * 1000=2,160,000,000

然后我就想是不是结果超出了数据类型的范围?

通过这个方法确定一下

System.out.println(Integer.MAX_VALUE);

结果是2147483647。

果然,当N等于26的时候,计算结果超出了整型的最大范围,这就是导致了最终的日期出现错误的根本原因!!

验证一下猜想。我把计算毫秒的表达式变为Long类型试试(在计算表达式后面加上L):

 DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
 for (int i = 0; i < 30; i++) {
      String time = df.format(System.currentTimeMillis()- i * 24 * 60 * 60 * 1000L);
      System.out.println(time);
      }

结果:

2019-10-10, 2019-10-09, 2019-10-08, 2019-10-07, 2019-10-06, 2019-10-05, 2019-10-04, 2019-10-03, 2019-10-02, 2019-10-01, 2019-09-30, 2019-09-29, 2019-09-28, 2019-09-27, 2019-09-26, 2019-09-25, 2019-09-24, 2019-09-23, 2019-09-22, 2019-09-21, 2019-09-20, 2019-09-19, 2019-09-18, 2019-09-17, 2019-09-16, 2019-09-15, 2019-09-14, 2019-09-13, 2019-09-12, 2019-09-11

Bug解决了!!

这个Bug耗费了我不少时间,在开发中也很容易被忽略,希望大家不要踩到这种坑才好。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值