今天在开会谈需求的时候,遇到了这么一个需求:要求动态的获得当前日期往前推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耗费了我不少时间,在开发中也很容易被忽略,希望大家不要踩到这种坑才好。

java mongo 日期范围_获取指定日期和它之前几天,之间的所有日期?千万不要踩了这个大坑!...相关推荐

  1. Java中时间格式化(获取指定时间)

    Java中时间格式化(获取指定时间,七天前) 1.通过获取当前系统时间,格式化后转为"yyyy-MM-dd HH:mm:ss"格式并输出: 2.可获取指定时间,如七天前,一年前等, ...

  2. java按季还款_Java 获取指定日期范围内的每个月,每季度,每一年

    /** *根据时间范围获得月份集 * @return */ public static List getRangeSet(String beginDate,String endDate){ /*    ...

  3. Java 网络实例一(获取指定主机的IP地址、查看端口是否已使用、获取本机ip地址及主机名、获取远程文件大小)

    获取指定主机的IP地址 import java.net.InetAddress; import java.net.UnknownHostException;public class GetIP {pu ...

  4. java 判断是否夏令时_确定指定日期的Java夏令时(DST)是否处于活动状态

    我有一个Java类,它占用一个位置的纬度/经度,并在夏时制开启和关闭时返回GMT偏移量.我正在寻找一个简单的方法来确定Java如果当前日期是在夏令时间,所以我可以应用正确的偏移量.目前,我只对美国时区 ...

  5. java calendar字符串显示_Java获取当前时间年月日、时间格式化打印、字符串转日期...

    package com.sysc.simple; import java.text.ParseException; import java.text.SimpleDateFormat; import ...

  6. java根据年月获取天数_获取指定年月的天数

    ### 通过传入日期查询当月的天数 java.util.Calendar中已经提供了获取天数的方法, 代码如下: ``` package top.itart; import java.text.Par ...

  7. java 获取包名类名_获取指定包名下的所有类的类名(全名)

    参考来源: 以下代码一键运行: package test; import java.io.File; import java.io.IOException; import java.net.JarUR ...

  8. antd 日期选择范围获取指定日期的0时0分0秒或23时59分59秒

    由于本人比较懒,直接上代码 <DatePicker.RangePicker style={{marginLeft: "3px", width: "250px&quo ...

  9. java文件绝对路径_获取文件夹文件绝对路径

    引用   linuxpro https://zhidao.baidu.com/question/59940919.html?fr=iks&word=DOS+%C3%FC%C1%EE&i ...

最新文章

  1. HTML5 手机端动态适配
  2. Tomcat 7 安装成功,启动后显示空白页问题
  3. [云炬创业基础笔记]第七张创业团队测试1
  4. 无法为类型 CuteEditor.Editor 授予有效的许可证。
  5. 20190904:(leetcode习题)合并两个有序数组
  6. DotNetty网络通信框架学习
  7. 学C语言开发能实现月薪12K吗?
  8. linux下大于2T的硬盘使用方法
  9. delphi中exit,abort,break,continue 的区别
  10. win7上Android环境搭建以及调试
  11. c语言程序输出数字图形,C语言数组应用之图形数字的输出
  12. python写数据到hive_Python数据篇之Pyhive
  13. 论开学第二个月干了点啥
  14. fftshift详解
  15. 【AI视野·今日CV 计算机视觉论文速览 第220期】Wed, 16 Jun 2021
  16. WEBRTC浅析(五)视频Nack包的发送判断逻辑以及数据流
  17. android ibeacon sdk,如何通过Android上的SDK更改iBeacon参数(UUID,Major,Minor,TxPower)的值...
  18. c代码生成matlab模块,使用 C Caller 模块集成 C 代码
  19. python离线安装selenium_python34怎么离线安装selenium
  20. javaweb成语接龙

热门文章

  1. ElasticSearch权威指南学习(索引管理)
  2. 使用for循环遍历文件、使用while循环遍历文件
  3. 荣耀8获吉尼斯世界纪录!18425米高空直播体验
  4. erlang开发工具之intellij idea基本使用
  5. Maven Ant 中截取字符串
  6. Mina的TCP的主要接口
  7. ubuntu上安装CLucene
  8. signature=ad248ee50cb35fb429594f302bf99ddf,动态源路由协议在无线自组网中的研究与应用...
  9. 第0003 天:论团队分工、成长
  10. php 复杂数组排序,如何利用php array_multisort函数 对数据库结果进行复杂排序