业务开发过程中需要对java.util.Date的时间进行设置,使用了void java.util.Date.setTime(long time)方法,但在测试过程中却发现millisecond超过某一定长度后出现了“逆流”,时间出现了回退现象。
现象描述
(1)我们先看一下正常情况下的例子,将当天时间增加10天
public static void main(String[] args) { Date now = new Date(); System.out.println("now time : " + now); now.setTime(now.getTime() + 60 * 60 * 24 * 1000 * 10); System.out.println("next1 time : " + now); }
返回结果如下:
now time : Thu Feb 09 11:26:28 CST 2017 next time : Sun Feb 19 11:26:28 CST 2017
从返回值可以看出时间设置成功,当前时间被往后推了10天。
(2)我们再看一下异常情况的例子,将当前时间增加365天
public static void main(String[] args) { Date now = new Date(); System.out.println("now time : " + now); now.setTime(now.getTime() + 60 * 60 * 24 * 1000 * 365); System.out.println("next2 time : " + now); }
返回结果如下:
now time : Thu Feb 09 11:39:16 CST 2017 next2 time : Sun Feb 26 12:19:45 CST 2017
从结果中可以看出被设置后的时间没有往后累加365天,反而只是加了十几天,时间还是停留在2017年,出现的结果和期望值不一样!
原因分析
仔细对比了两个例子的代码,唯一不一样的地方就是一个时间乘以了10,另一个时间乘以了365,其他代码都是一样的,百思不得其解。
多试了几种异常情况后,发现乘以的天数达到某一阈值后会出现时间回退现象,而在这个阈值之前的设置都是正常的,并且回退出现循环情况。
发现这个规律后,第一想到的就是数据值长度超出某数据类型的最大值后被循环截断了。这时再分析下数据表达式,发现“60 * 60 * 24 * 1000 * 365”这个地方可能存在问题,换一种方式处理后果然验证了猜想!
public static void main(String[] args) { Date now = new Date(); System.out.println("now time : " + now); long addTime = 60 * 60 * 24 * 1000 * 365L; now.setTime(now.getTime() + addTime); System.out.println("next3 time : " + now); }
返回结果正常:
now time : Thu Feb 09 11:51:37 CST 2017 next3 time : Fri Feb 09 11:51:37 CST 2018
现在可以看出,是“60 * 60 * 24 * 1000 * 365”的计算结果被当成int型数据截断了!如果显示的将其标识为long型数据就没有问题了。
这个也提醒我们在处理时间毫秒等长数据类型时一定要显示的使用long型,即使下面这种前置声明方式也会有问题:
public static void main(String[] args) { Date now = new Date(); System.out.println("now time : " + now); long addTime = 60 * 60 * 24 * 1000 * 365; now.setTime(now.getTime() + addTime); System.out.println("next4 time : " + now); }
异常结果:
now time : Thu Feb 09 11:55:45 CST 2017 next4 time : Sun Feb 26 12:36:14 CST 2017
这段测试代码和上一段唯一不一样的地方在于:
long addTime = 60 * 60 * 24 * 1000 * 365L long addTime = 60 * 60 * 24 * 1000 * 365;
通过最后这个例子相信大家已经知道这个时间设置问题的本质原因了!
相关推荐
10.javaDate类.zip10.javaDate类.zip10.javaDate类.zip10.javaDate类.zip10.javaDate类.zip10.javaDate类.zip10.javaDate类.zip10.javaDate类.zip10.javaDate类.zip10.javaDate类.zip10.javaDate类.zip10.javaDate类...
java.util.Date与java.sql.Date互转及字符串转换为日期时间格式.docx
java.sql.date与java.util.date.pdf
详细介绍java.util.Date和java.sql.Date相互转换的多种方法总结,希望对大家有帮助
php报时区错误,按照网上说的改时间date.timezone... You are *required* to use the date.timezone setting or the date_default_timezone_set() function. In case you used any of those methods and you are still
Java的java.util.Date类是Java初的时间类之一。该类的大部分方法已不推荐使用,取而代之的是java.util.Calendar类。不过你仍然可以使用java.util.Date类去表示某个时间。下面是一个如何实例化java.util.Date的例子:...
java_sql_Date与java_util_Date转换
类型转换 ( Java.util.date与java.sql.date区别和转换
NextDate.java白盒测试NextDate.java白盒测试NextDate.java白盒测试NextDate.java白盒测试NextDate.java白盒测试
主要给大家分享了关于JAVA String转化成java.sql.date和java.sql.time的方法,文中给出了详细的示例代码,相信对大家具有一定的参考价值,需要的朋友们下面来一起看看吧。
此java文件包括常用的日期类型之间的转换,包括java.util.Date、java.sql.Date、String之间的任意类型、格式转换......
java.lang.IllegalArgumentException Cannot format given Object as a Date
date.timezone设置php5默认date.timezone为utc,改为date.timezone = PRC即可解决时间相差八小时的问题,但我在php的官方文档中看了半天也没找到这个参数啊
date.timezone设置php5默认date.timezone为utc,改为date.timezone = PRC即可解决时间相差八小时的问题,但我在php的官方文档中看了半天也没找到这个参数啊 虽然知道这个参数表示“中华人民共和国”的意思,但官方...
java 9 中引入了模块的概念,默认情况下,Java SE中将不再包含java EE 的Jar包 而在 java 6/7 / 8 时关于这个API 都是捆绑在
now.setTime(date); int today = now.get(Calendar.DAY_OF_WEEK); int first_day_of_week = now.get(Calendar.DATE) + 2 - today; // 星期一 now.set(Calendar.DATE, first_day_of_week); return now....