Java以1970年1月1日0時為紀元,用long型毫秒數表示時間。Date、DateFormat、GregorianCalendar三大核心類構成日期處理體系。
Date now = new Date(); // 當前時間
long timestamp = now.getTime(); // 毫秒數
// 輸出示例:972568255150
long範圍可覆蓋約2.9億年,滿足絕大多數場景。
DateFormat df = DateFormat.getDateInstance(); // 默認
DateFormat df1 = DateFormat.getDateInstance(DateFormat.SHORT); // 11/8/00
DateFormat df2 = DateFormat.getDateInstance(DateFormat.MEDIUM); // Nov 8, 2000
DateFormat df3 = DateFormat.getDateInstance(DateFormat.LONG); // November 8, 2000
DateFormat df4 = DateFormat.getDateInstance(DateFormat.FULL); // Wednesday, November 8, 2000
同一代碼在不同Locale下輸出不同格式(如瑞典語輸出2000-nov-08)。生產環境建議顯式指定Locale避免不一致:
DateFormat df = DateFormat.getDateInstance(DateFormat.LONG, Locale.US);
String ds = "November 1, 2000";
Date d = DateFormat.getDateInstance().parse(ds); // 拋出ParseException需捕獲
// 月份從0開始:0=一月,11=十二月
GregorianCalendar firstFlight = new GregorianCalendar(1903, Calendar.DECEMBER, 17);
// 或簡寫
GregorianCalendar firstFlight = new GregorianCalendar(1903, 11, 17);
Date d = firstFlight.getTime(); // Calendar → Date
String s = DateFormat.getDateInstance().format(d);
GregorianCalendar cal = new GregorianCalendar(1872, Calendar.OCTOBER, 2);
cal.add(GregorianCalendar.DATE, 80); // 80天後
cal.add(Calendar.YEAR, 15); // 15年後
cal.add(Calendar.MONTH, 3); // 3個月後
注意:add()修改原對象。需保留原值時應創建副本:
GregorianCalendar gc3 = new GregorianCalendar(2000, Calendar.JANUARY, 1);
gc1.add(Calendar.YEAR, 1); // gc1、gc2變為2001,gc3保持2000
依艾賓浩斯遺忘曲線,計算學習後1天、1周、1月、3月、1年的複習時間點:
public class ReviewDates {
private GregorianCalendar firstDay, oneDay, oneWeek, oneMonth, oneQuarter, oneYear;
public ReviewDates(GregorianCalendar date) {
int y = date.get(Calendar.YEAR), m = date.get(Calendar.MONTH), d = date.get(Calendar.DATE);
firstDay = new GregorianCalendar(y, m, d);
oneDay = new GregorianCalendar(y, m, d); oneDay.add(Calendar.DATE, 1);
oneWeek = new GregorianCalendar(y, m, d); oneWeek.add(Calendar.DATE, 7);
oneMonth = new GregorianCalendar(y, m, d); oneMonth.add(Calendar.MONTH, 1);
oneQuarter = new GregorianCalendar(y, m, d); oneQuarter.add(Calendar.MONTH, 3);
oneYear = new GregorianCalendar(y, m, d); oneYear.add(Calendar.YEAR, 1);
}
public void listDates() {
DateFormat df = DateFormat.getDateInstance(DateFormat.LONG);
System.out.println("開始:" + df.format(firstDay.getTime()));
System.out.println("複習點:" + df.format(oneDay.getTime()) + " / "
+ df.format(oneWeek.getTime()) + " / " + df.format(oneMonth.getTime()) + " / "
+ df.format(oneQuarter.getTime()) + " / " + df.format(oneYear.getTime()));
}
}
Date:毫秒級時間戳,底層存儲DateFormat:格式化/解析,敏感於LocaleGregorianCalendar:日期運算、字段訪問、任意日期構建現代項目建議使用Java 8+的java.time包(LocalDate、DateTimeFormatter等),線程安全且API更直觀。