關于Date使用不當的bug
關于Date使用不當的bug
1、背景
用戶調用接口,傳入一個參數分鐘,表示想要查詢距離現在多少分鐘的記錄。
有的時候會查不到記錄。
2、排查過程
大致代碼。
- 獲取當前的時間的date對象now,通過now的時間戳計算前beforeMinute的時間戳,轉換成date對象
- 查詢
executeTime >= before && executeTime <= now && status == 1的記錄
@GetMapping("/test")
public void testMongo(Integer beforeMinute) {
// 計算執行時間前后時間
Date now = new Date(); // 獲取當前時間的Date對象
Date before = new Date(now.getTime() - beforeMinute * 60 * 1000); // 獲取前beforeMinute的Date對象
andCriteriaList.add(Criteria.where("executeTime").gte(before));
andCriteriaList.add(Criteria.where("executeTime").lte(now));
andCriteriaList.add(Criteria.where("status").is(Integer.parseInt("1"))); // 狀態為 1
Criteria combinedCriteria = new Criteria();
combinedCriteria.andOperator(andCriteriaList.toArray(new Criteria[0]));
Query query = new Query();
query.addCriteria(combinedCriteria);
List<AuditLogDownloadBean> list = mongoTemplate.find(query, AuditLogDownloadBean.class);
for (AuditLogDownloadBean bean : list) {
System.out.println(bean.getId() + " "+ bean.getExecuteTime() + " " + bean.getJobName());
}
return ;
}
經過debug,問題出在構造before的date對象上,有時會出現before計算出來的時間戳會比now還要大,所以導致查不到數據。
Date before = new Date(now.getTime() - beforeMinute * 60 * 1000);
/**
當查詢三天前的記時,傳入的參數=3x24x60=43200
此時,beforeMinute * 60 * 1000 = 2,592,000,000 共十位,而int的最大值也是十位 2,147,483,647,所以產生了整型溢出,
整個表達式的值相當于 now.getTime() - (-1702967296), 所以會比now還要大,最終導致查不到數據。
*/
// 改正
Date before = new Date(now.getTime() - beforeMinute * 60L * 1000);
3、總結
- Java 中數字字面量默認是整型的
- 當一個表達式中含有變量時,要注意其是否可能產生整型溢出
- 當一個表達式中包含Long類型時,整個表達式的值會向Long轉變
本文來自博客園,作者:永恒&,轉載請注明原文鏈接:http://www.rzrgm.cn/Sun-yuan/p/17281381.html

浙公網安備 33010602011771號