為什么阿里開發(fā)手冊不建議使用Date類?
作者:哪吒
在日常編碼中,基本上99%的項目都會有一個DateUtil工具類,而時間工具類里用的最多的就是java.util.Date。在進行安全掃描的時候,提示java.util.Date存在安全漏洞,有什么漏洞,如何解決?
在日常編碼中,基本上99%的項目都會有一個DateUtil工具類,而時間工具類里用的最多的就是java.util.Date。
大家都這么寫,這還能有問題??
當你的“默認常識”出現(xiàn)問題,這個打擊,就是毀滅性的。
但是,在進行安全掃描的時候,提示java.util.Date存在安全漏洞。
public class DateUtil {
/**
* 日期格式化
*/
public static String formatDate(Date date, String format) {
SimpleDateFormat sdf = new SimpleDateFormat(format);
return sdf.format(date);
}
/**
* 字符串轉Date
*/
public static Date parseDate(String dateStr, String format) throws ParseException {
SimpleDateFormat sdf = new SimpleDateFormat(format);
return sdf.parse(dateStr);
}
/**
* 獲取指定格式的當前時間
*/
public static String getCurrentDate(String format) {
// 獲取當前時間
Date currentDate = new Date();
// 定義日期格式
SimpleDateFormat dateFormat = new SimpleDateFormat(format);
return dateFormat.format(currentDate);
}
}
把組件風險列表截圖+DateUtil工具類發(fā)給我的編程小助手ChatGPT4o。
Prompt:在進行安全掃描的時候,提示java.util.Date存在安全漏洞,有什么漏洞,如何解決?
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.LocalDate;
import java.time.LocalTime;
import java.time.ZoneId;
import java.util.Date;
public class DateUtil {
// 日期格式化
public static String formatDate(LocalDateTime dateTime, String format) {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(format);
return dateTime.format(formatter);
}
// 字符串轉Date
public static LocalDateTime parseDate(String dateStr, String format) {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(format);
return LocalDateTime.parse(dateStr, formatter);
}
// 獲取指定格式的當前時間
public static String getCurrentDate(String format) {
// 獲取當前時間
LocalDateTime currentDate = LocalDateTime.now();
// 定義日期格式
DateTimeFormatter dateFormat = DateTimeFormatter.ofPattern(format);
return currentDate.format(dateFormat);
}
// 將 java.util.Date 轉為 java.time.LocalDateTime
public static LocalDateTime convertToLocalDateTime(Date date) {
return LocalDateTime.ofInstant(date.toInstant(), ZoneId.systemDefault());
}
// 將 java.time.LocalDateTime 轉為 java.util.Date
public static Date convertToDate(LocalDateTime dateTime) {
return Date.from(dateTime.atZone(ZoneId.systemDefault()).toInstant());
}
}
以下是Date設計上的主要缺陷:
- Date 這個名稱本身就具有誤導性。它實際上表示的是一個時間點,而非日期。因此,更為恰當?shù)拿Q應為 Instant,這與 java.time 中的對應類型相符。
- 它不是一個最終類,這導致了諸如 java.sql.Date 等不良的繼承使用。java.sql.Date 旨在表示一個日期,但由于名稱相同而常常引起混淆。
- Date 是可變的,而日期/時間類型通常是自然值,適合用不可變類型進行建模。Date 的可變性(例如通過 setTime 方法)迫使開發(fā)人員不得不創(chuàng)建大量防御性副本,以確保代碼的安全性。
- Date 在許多地方(包括 toString() 方法)隱式使用系統(tǒng)本地時區(qū),這常常讓開發(fā)人員感到困惑。更多細節(jié)可以參見“時間點是什么”部分。
- Date 的月份編號從 0 開始,這是借鑒自 C 語言的設計。這種設計導致了大量的“偏一”錯誤。同樣,年份編號從 1900 開始,也是借鑒自 C 語言。顯然,當 Java 出現(xiàn)時,我們已經(jīng)意識到這種設計不利于代碼的可讀性。
- Date 的方法命名也不清晰。getDate() 方法返回的是月中的某一天,而 getDay() 方法返回的是星期幾。給這些方法起更具描述性的名稱并不會很困難,但遺憾的是,這并未實現(xiàn)。
- 對于是否支持閏秒,Date 的表現(xiàn)也不明確。文檔中指出“一秒鐘由一個 0 到 61 的整數(shù)表示;60 和 61 僅在實際正確跟蹤閏秒的 Java 實現(xiàn)中出現(xiàn)?!?我強烈懷疑,大多數(shù)開發(fā)人員(包括我自己)都默認認為 getSeconds() 方法的返回值范圍是 0-59。
- Date 類的方法對參數(shù)范圍的要求非常寬松,這沒有明顯的理由。例如,方法允許日期參數(shù)為 1 月 32 日,并解釋為 2 月 1 日。這種寬松的參數(shù)范圍在實際應用中并不常見,反而增加了使用的復雜性和出錯的風險。
盡管還能找到更多的問題,但那會顯得過于挑剔。
責任編輯:姜華
來源:
哪吒編程