import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
/**
* 獲取相對於當前時間的日期
* @param daysOffset 正數=未來N天,負數=過去N天,0=今天
* @return Timestamp 對象(含時分秒),可直接寫入數據庫
*/
public static Timestamp getRelativeDate(int daysOffset) {
Calendar cal = Calendar.getInstance(); // 線程安全:每次調用創建新實例
cal.add(Calendar.DAY_OF_MONTH, daysOffset);
Date date = cal.getTime();
// 格式化為 "yyyy-MM-dd HH:mm:ss" 再解析為 Timestamp,去除毫秒差異
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String formatted = sdf.format(date);
return Timestamp.valueOf(formatted);
}
Calendar.getInstance() 返回新實例,避免 SimpleDateFormat 非線程安全問題(此處 SimpleDateFormat 也是局部變量,安全)。PreparedStatement.setTimestamp(),避免 java.util.Date 轉換麻煩。import java.time.LocalDateTime;
import java.time.ZoneId;
import java.sql.Timestamp;
/**
* Java 8+ 現代寫法:不可變、線程安全、API 清晰
*/
public static Timestamp getRelativeDateModern(int daysOffset) {
LocalDateTime ldt = LocalDateTime.now().plusDays(daysOffset);
return Timestamp.valueOf(ldt); // LocalDateTime 直接轉 Timestamp,無需格式化字符串
}
優勢:無 SimpleDateFormat 開銷、不可變對象天然線程安全、鏈式調用可讀性強、支持時區 .atZone(ZoneId.of("Asia/Shanghai"))。
// 3 天前
Timestamp threeDaysAgo = getRelativeDate(-3);
// 明天
Timestamp tomorrow = getRelativeDate(1);
// 今天 00:00:00
Timestamp todayStart = getRelativeDate(0); // 注意:此方法返回當前時刻,非當天起始
// 如需當天起始:
LocalDateTime todayZero = LocalDate.now().atStartOfDay();
ThreadLocal 緩存。daysOffset 明確語義,文檔註釋說明正負含義。