美文网首页
线上问题之你知道Integer多大吗

线上问题之你知道Integer多大吗

作者: 土豆肉丝盖浇饭 | 来源:发表于2018-11-27 17:44 被阅读9次

问题复盘

我们系统有个任务订单,在每天的某个时间点生成一个取货时间为xxx的订单,取货时间需要每天生成为当天的,所以每天生成订单的时候会替换取货时间的日期部分(年月日)。

还有一个背景是,我们数据库内存的是Integer,而实际操作时间需要用Long类型。

那么下面我们来看下这段问题代码,你能发现那里出问题了么。

//input:1536748290
 private Integer changeDateToCurrentDate(Integer time){
        Date date = new Date(time*1000);//转换为毫秒级时间戳
        Date now = new Date();
        date.setYear(now.getYear());
        date.setMonth(now.getMonth());
        date.setDate(now.getDate());
        return new Long(date.getTime()/1000).intValue();//转换为秒级时间戳
    }

......

下面揭晓答案,time*1000会存在溢出。

我们用Integer保存秒级时间戳。
Integer最大值能够支持到2038年,够用了。

System.out.println(new Date(0X7FFFFFFF*(long)1000));
//output:Tue Jan 19 11:14:07 CST 2038

但是我想通过Date对日期进行转换的时候,需要先转换成毫秒级时间戳,然后修改日期后,再除以1000输出秒级时间戳。

那么问题就出现了。

现在的秒级时间戳已经到达10位,Integer.MAX_VALUE=2147483647,所以转换为毫秒时间戳就肯定溢出了。

最终得到的时间戳就会出现日期是对的,时间错乱的问题。

修复这个问题也很简单,jvm不会自动将int*int转换为long,那么我们只需要将其中一个参数强制转换为long即可。

Date date = new Date((long)time*1000);

总结

对Integer或者其他数字类型进行操作时,要注意溢出这个问题。熟记每种数字类型的极限值的量级。

下面是我公众号,大家可以关注下。


image

相关文章

网友评论

      本文标题:线上问题之你知道Integer多大吗

      本文链接:https://www.haomeiwen.com/subject/zssbgftx.html