一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務(wù)器之家:專(zhuān)注于服務(wù)器技術(shù)及軟件下載分享
分類(lèi)導(dǎo)航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術(shù)|正則表達(dá)式|C/C++|IOS|C#|Swift|Android|VB|R語(yǔ)言|JavaScript|易語(yǔ)言|vb.net|

服務(wù)器之家 - 編程語(yǔ)言 - Java教程 - Java中在時(shí)間戳計(jì)算的過(guò)程中遇到的數(shù)據(jù)溢出問(wèn)題

Java中在時(shí)間戳計(jì)算的過(guò)程中遇到的數(shù)據(jù)溢出問(wèn)題

2021-12-24 19:56翎野君 Java教程

今天在跑定時(shí)任務(wù)的過(guò)程中,發(fā)現(xiàn)有一個(gè)任務(wù)在設(shè)置數(shù)據(jù)的查詢(xún)時(shí)間范圍異常,出現(xiàn)了開(kāi)始時(shí)間戳比結(jié)束時(shí)間戳大的奇怪現(xiàn)象,計(jì)算時(shí)間戳的代碼大致如下。

背景

Java中在時(shí)間戳計(jì)算的過(guò)程中遇到的數(shù)據(jù)溢出問(wèn)題

今天在跑定時(shí)任務(wù)的過(guò)程中,發(fā)現(xiàn)有一個(gè)任務(wù)在設(shè)置數(shù)據(jù)的查詢(xún)時(shí)間范圍異常,出現(xiàn)了開(kāi)始時(shí)間戳比結(jié)束時(shí)間戳大的奇怪現(xiàn)象,計(jì)算時(shí)間戳的代碼大致如下。

  1. package com.lingyejun.authenticator;
  2. public class IntegerTest {
  3. public static void main(String[] args) {
  4. long endTime = System.currentTimeMillis();
  5. long startTime = endTime - 30 * 24 * 60 * 60 * 1000;
  6. System.out.println("end : " + endTime);
  7. System.out.println("start : " + startTime);
  8. }
  9. }

先放出結(jié)論:因?yàn)閖ava中整數(shù)默認(rèn)是int類(lèi)型,在計(jì)算的過(guò)程中30 * 24 * 60 * 60 * 1000計(jì)算結(jié)果大于Integer.MAX_VALUE,所以出現(xiàn)了數(shù)據(jù)溢出,從而導(dǎo)致了計(jì)算結(jié)果不準(zhǔn)確的問(wèn)題。

驗(yàn)證

我們將上面的代碼稍稍改造一下,方便我們確認(rèn)定位問(wèn)題,調(diào)整后的代碼如下:

  1. package com.lingyejun.authenticator;
  2. public class IntegerTest {
  3. public static long calcStartTime(long endTime, long minusMills) {
  4. System.out.println("end : " + endTime + " minus mills : " + minusMills);
  5. long startTime = endTime - minusMills;
  6. System.out.println("start: " + startTime);
  7. return startTime;
  8. }
  9. public static void main(String[] args) {
  10. long nowTime = System.currentTimeMillis();
  11. long a = 30 * 24 * 60 * 60 * 1000;
  12. calcStartTime(nowTime, a);
  13. }
  14. }

結(jié)果如下:

  1. end : 1560869539864 minus mills : -1702967296
  2. start: 1562572507160

這和我們的預(yù)期不一樣,因?yàn)?0 * 86400000 = 2592000000,但是計(jì)算出來(lái)卻是:-1702967296。

到這里想必大家都知道原因了,這是因?yàn)閖ava中整數(shù)的默認(rèn)類(lèi)型是整型int,而int的最大值是2147483647,

在代碼中java是先計(jì)算右值,再賦值給long變量的。在計(jì)算右值的過(guò)程中(int型相乘)發(fā)生溢出,然后將溢出后截?cái)嗟闹蒂x給變量,導(dǎo)致了結(jié)果不準(zhǔn)確。

將代碼做一下小小的改動(dòng),再看一下。

  1. package com.lingyejun.authenticator;
  2. public class IntegerTest {
  3. public static long calcStartTime(long endTime, long minusMills) {
  4. System.out.println("end : " + endTime + " minus mills : " + minusMills);
  5. long startTime = endTime - minusMills;
  6. System.out.println("start: " + startTime);
  7. return startTime;
  8. }
  9. public static void main(String[] args) {
  10. long nowTime = System.currentTimeMillis();
  11. long a = 30 * 24 * 60 * 60 * 1000L;
  12. calcStartTime(nowTime, a);
  13. }
  14. }

結(jié)果為

  1. end : 1560869539864 minus mills : 2592000000
  2. start: 1558277539864

似乎這樣應(yīng)該就沒(méi)有什么問(wèn)題了,但是這樣就真的保險(xiǎn)了嗎,如果我要把30調(diào)整為24856(Integer.MAX_VALUE / 86400 = 24855),即改為:long a = 24856 * 24 * 60 * 60 * 1000L 那么同樣會(huì)出現(xiàn)溢出。

因?yàn)閖ava的運(yùn)算規(guī)則從左到右,再與最后一個(gè)long型的1000相乘之前就已經(jīng)溢出,所以結(jié)果也不對(duì),正確的方式應(yīng)該如下:long a = 24856L * 24 * 60 * 60 * 1000。

  1. package com.lingyejun.authenticator;
  2. public class IntegerTest {
  3. public static long calcStartTime(long endTime, long minusMills) {
  4. System.out.println("end : " + endTime + " minus mills : " + minusMills);
  5. long startTime = endTime - minusMills;
  6. System.out.println("start: " + startTime);
  7. return startTime;
  8. }
  9. public static void main(String[] args) {
  10. long a = 30L * 24 * 60 * 60 * 1000;
  11. calcStartTime(nowTime, a);
  12. }
  13. }

原文鏈接:https://www.toutiao.com/a7044145497078088228/

延伸 · 閱讀

精彩推薦
  • Java教程Java使用SAX解析xml的示例

    Java使用SAX解析xml的示例

    這篇文章主要介紹了Java使用SAX解析xml的示例,幫助大家更好的理解和學(xué)習(xí)使用Java,感興趣的朋友可以了解下...

    大行者10067412021-08-30
  • Java教程升級(jí)IDEA后Lombok不能使用的解決方法

    升級(jí)IDEA后Lombok不能使用的解決方法

    最近看到提示IDEA提示升級(jí),尋思已經(jīng)有好久沒(méi)有升過(guò)級(jí)了。升級(jí)完畢重啟之后,突然發(fā)現(xiàn)好多錯(cuò)誤,本文就來(lái)介紹一下如何解決,感興趣的可以了解一下...

    程序猿DD9332021-10-08
  • Java教程Java8中Stream使用的一個(gè)注意事項(xiàng)

    Java8中Stream使用的一個(gè)注意事項(xiàng)

    最近在工作中發(fā)現(xiàn)了對(duì)于集合操作轉(zhuǎn)換的神器,java8新特性 stream,但在使用中遇到了一個(gè)非常重要的注意點(diǎn),所以這篇文章主要給大家介紹了關(guān)于Java8中S...

    阿杜7482021-02-04
  • Java教程xml與Java對(duì)象的轉(zhuǎn)換詳解

    xml與Java對(duì)象的轉(zhuǎn)換詳解

    這篇文章主要介紹了xml與Java對(duì)象的轉(zhuǎn)換詳解的相關(guān)資料,需要的朋友可以參考下...

    Java教程網(wǎng)2942020-09-17
  • Java教程Java實(shí)現(xiàn)搶紅包功能

    Java實(shí)現(xiàn)搶紅包功能

    這篇文章主要為大家詳細(xì)介紹了Java實(shí)現(xiàn)搶紅包功能,采用多線(xiàn)程模擬多人同時(shí)搶紅包,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙...

    littleschemer13532021-05-16
  • Java教程Java BufferWriter寫(xiě)文件寫(xiě)不進(jìn)去或缺失數(shù)據(jù)的解決

    Java BufferWriter寫(xiě)文件寫(xiě)不進(jìn)去或缺失數(shù)據(jù)的解決

    這篇文章主要介紹了Java BufferWriter寫(xiě)文件寫(xiě)不進(jìn)去或缺失數(shù)據(jù)的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望...

    spcoder14552021-10-18
  • Java教程20個(gè)非常實(shí)用的Java程序代碼片段

    20個(gè)非常實(shí)用的Java程序代碼片段

    這篇文章主要為大家分享了20個(gè)非常實(shí)用的Java程序片段,對(duì)java開(kāi)發(fā)項(xiàng)目有所幫助,感興趣的小伙伴們可以參考一下 ...

    lijiao5352020-04-06
  • Java教程小米推送Java代碼

    小米推送Java代碼

    今天小編就為大家分享一篇關(guān)于小米推送Java代碼,小編覺(jué)得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧...

    富貴穩(wěn)中求8032021-07-12
主站蜘蛛池模板: 亚洲电影成人 成人影院 | 四虎永久在线精品国产馆v视影院 | 91短视频社区在线观看 | 免费一区 | 插鸡视频在线观看 | 男人的天堂欧美 | 日产国产精品亚洲系列 | 亚洲国产五月综合网 | 波多野给衣一区二区三区 | 顶级尤物极品女神福利视频 | 无码中文字幕热热久久 | 日本人交换乱理伦片 | 亚洲精品九色在线网站 | 缴情五月天 | 国产 日韩 欧美视频二区 | 成人国产第一区在线观看 | 国产自拍偷拍自拍 | 亚洲精品乱码久久久久久蜜桃图片 | b站免费| 美国video| 添逼逼视频| 国产精品日本一区二区不卡视频 | 欧美人在线一区二区三区 | 成人丁香乱小说 | h肉动漫在线视频无修无遮挡 | 精品视频网站 | 动漫美女被褥吸奶漫画漫画 | 国产福利不卡视频在免费 | 千金肉奴隶免费观看 | 久久99r66热这里只有精品 | 天天狠天天天天透在线 | blacked黑人hd2021| 午夜欧美精品久久久久久久 | 网www天堂资源在线 王淑兰与铁柱全文免费阅读 | 污书屋| 国精品午夜dy8888狼人 | 国产中文字幕 | 精品四虎 | 色综合国产 | 欧美日韩国产一区二区三区不卡 | 欧美8x8x |