java.util.Date:時間戳(毫秒精度),多數方法已過時。java.util.Calendar:抽象基類,GregorianCalendar 為具體實現,支援字段操作與國際化。java.text.SimpleDateFormat:格式化/解析,非線程安全。java.sql.Date、Time、Timestamp:JDBC 專用,對應數據庫 DATE/TIME/DATETIME。Calendar cal = Calendar.getInstance();
cal.clear(); // 必須先 clear,否則繼承系統當前時間殘留字段
cal.set(Calendar.YEAR, year);
cal.set(Calendar.MONTH, month - 1); // 月份 0-based
int days = cal.getActualMaximum(Calendar.DAY_OF_MONTH);
// Calendar → Date
Date date = cal.getTime();
// Date → Calendar
Calendar cal = Calendar.getInstance();
cal.setTime(date);
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String formatted = sdf.format(new Date()); // 2024-05-18 14:30:00
// 解析
Date parsed = sdf.parse("2024-05-18 14:30:00");
// 某日是第幾周
cal.set(2024, Calendar.MAY, 18);
int weekOfYear = cal.get(Calendar.WEEK_OF_YEAR);
// 第 N 周的周一日期
cal.set(2024, Calendar.JANUARY, 1);
cal.set(Calendar.WEEK_OF_YEAR, n);
cal.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
add(field, amount):正規加減,會進位(如 8/31 + 1 天 = 9/1)。roll(field, amount):本字段循環,不進位(8/31 roll 1 天 = 8/1)。// 推薦:基於 Calendar DAY_OF_YEAR 與年份差累加,避免 DST 導致的毫秒法誤差
public int getDaysBetween(Calendar d1, Calendar d2) {
if (d1.after(d2)) { Calendar tmp = d1; d1 = d2; d2 = tmp; }
int days = d2.get(Calendar.DAY_OF_YEAR) - d1.get(Calendar.DAY_OF_YEAR);
int y2 = d2.get(Calendar.YEAR);
if (d1.get(Calendar.YEAR) != y2) {
d1 = (Calendar) d1.clone();
do {
days += d1.getActualMaximum(Calendar.DAY_OF_YEAR);
d1.add(Calendar.YEAR, 1);
} while (d1.get(Calendar.YEAR) != y2);
}
return days;
}
// String → Date → Long
SimpleDateFormat sdf = new SimpleDateFormat("M/dd/yyyy hh:mm:ss a", Locale.US);
Date d = sdf.parse("5/13/2003 10:31:37 AM");
long ts = d.getTime();
// Long → Date → String
SimpleDateFormat out = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String str = out.format(new Date(ts));
// "2003-05 5 星期五" → 具體日期
SimpleDateFormat f = new SimpleDateFormat("yyyy-MM w E");
Date d = f.parse("2003-05 5 星期五");
// 判斷星期
SimpleDateFormat wf = new SimpleDateFormat("E");
String week = wf.format(date); // "週二"
| 數據庫類型 | Java 類型 | 適用場景 |
|---|---|---|
| Oracle DATE | java.sql.Date | 僅需年月日 |
| SQL Server DATETIME | java.sql.Timestamp | 需年月日時分秒毫秒 |
| MySQL DATETIME | java.sql.Timestamp | 同左 |
// 通用字符串 → Timestamp
public static Timestamp string2Time(String s) throws ParseException {
SimpleDateFormat f = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS", Locale.ENGLISH);
f.setLenient(false);
return new Timestamp(f.parse(s).getTime());
}
// 通用字符串 → java.sql.Date
public static java.sql.Date string2Date(String s) throws ParseException {
SimpleDateFormat f = new SimpleDateFormat("yyyy-MM-dd", Locale.ENGLISH);
f.setLenient(false);
return new java.sql.Date(f.parse(s).getTime());
}
Calendar.MONTH 0=1月,11=12月。SimpleDateFormat 非線程安全,請使用 ThreadLocal 或 Java 8+ DateTimeFormatter。TimeZone,避免夏令時導致日期偏移。setLenient(false),防止「2024-02-30」被自動糾正為 3/1。掌握這套模板,應對 90% 以上的 Java 日期時間業務場景綽綽有餘。