java.util.Date 封裝日期時間,精確到毫秒。兩個建構子:Date()(當前時間)、Date(long millisec)(1970/1/1 起毫秒數)。
| 方法 | 說明 |
|---|---|
after/before(Date) | 比較前後關係 |
compareTo(Date) | 比較大小(0 相等、負數較早、正數較晚) |
equals(Object) | 判斷相等 |
getTime() | 取得 1970 起毫秒數 |
setTime(long) | 設定毫秒數 |
toString() | 轉字串(如 Mon May 04 09:51:52 CDT 2013) |
Date now = new Date();
System.out.println(now.toString());
getTime() 取毫秒數直接比較before()、after()、equals()compareTo()(實作 Comparable)非執行緒安全,多執行緒環境需同步或使用 ThreadLocal。
| 字元 | 意義 | 範例 |
|---|---|---|
| y | 年 | 2001 / 01 |
| M | 月 | July / 07 |
| d | 日 | 10 |
| H | 時 (0-23) | 22 |
| h | 時 (1-12) | 10 |
| m | 分 | 30 |
| s | 秒 | 55 |
| S | 毫秒 | 234 |
| E | 星期 | Tuesday |
| a | AM/PM | PM |
| z | 時區 | PST |
Date dNow = new Date();
SimpleDateFormat ft = new SimpleDateFormat("E yyyy.MM.dd 'at' hh:mm:ss a zzz");
System.out.println("Current Date: " + ft.format(dNow));
// Current Date: Sun 2004.07.18 at 04:14:09 PM PDT
SimpleDateFormat ft = new SimpleDateFormat("yyyy-MM-dd");
String input = "2007-12-01";
try {
Date t = ft.parse(input);
System.out.println(t); // Sat Dec 01 00:00:00 GMT 2007
} catch (ParseException e) {
System.out.println("Unparseable: " + ft);
}
使用 %t + 轉換字元:
| 轉換 | 說明 | 範例 |
|---|---|---|
%tc | 完整日期時間 | Mon May 04 09:51:52 CDT 2009 |
%tF | ISO 8601 日期 | 2004-02-09 |
%tT | 24 小時時間 | 18:05:19 |
%tr | 12 小時時間 | 06:05:19 pm |
%tY | 4 位年 | 2004 |
%tm | 2 位月 | 02 |
%td | 2 位日 | 09 |
%tB | 月份全名 | February |
%tb | 月份縮寫 | Feb |
%tA | 星期全名 | Monday |
%ta | 星期縮寫 | Mon |
System.out.printf("%1$s %2$tB %2$td, %2$tY", "Due date:", date);
// Due date: February 09, 2004
// 或使用 < 標記復用前一引數:
System.out.printf("%s %tB %<te, %<tY", "Due date:", date);
// 休眠 3 秒
Thread.sleep(1000 * 3);
// 測量時間間隔(毫秒)
long start = System.currentTimeMillis();
// ... 執行任務 ...
long end = System.currentTimeMillis();
System.out.println("耗時: " + (end - start) + " ms");
Calendar 為抽象類,透過 Calendar.getInstance() 取得具體實作(預設 GregorianCalendar)。
| 常數 | 意義 |
|---|---|
YEAR | 年 |
MONTH | 月 (0-11,需 +1) |
DATE / DAY_OF_MONTH | 日 |
HOUR_OF_DAY | 24 制時 |
MINUTE | 分 |
SECOND | 秒 |
DAY_OF_WEEK | 星期 (1=週日, 2=週一...) |
Calendar c = Calendar.getInstance();
// 設定特定日期
c.set(2009, 5, 12); // 月份 0 基礎,6月 = 5
// 單一欄位設定
c.set(Calendar.DATE, 10);
// 加減運算(自動進位)
c.add(Calendar.DATE, 10); // 10 天后
c.add(Calendar.MONTH, -1); // 1 月前
int year = c.get(Calendar.YEAR);
int month = c.get(Calendar.MONTH) + 1;
int day = c.get(Calendar.DATE);
int hour = c.get(Calendar.HOUR_OF_DAY);
int dow = c.get(Calendar.DAY_OF_WEEK); // 1=週日
支援公曆(AD/BC 紀元),提供豐富建構子與工具方法:
isLeapYear(year):判斷閏年getActualMaximum(MONTH):取得當月最大天數roll(field, up):單一欄位增減(不影響較大欄位)GregorianCalendar gc = new GregorianCalendar();
String[] months = {"Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"};
System.out.println("Date: " + months[gc.get(Calendar.MONTH)] + " " + gc.get(Calendar.DATE) + " " + gc.get(Calendar.YEAR));
System.out.println("Time: " + gc.get(Calendar.HOUR) + ":" + gc.get(Calendar.MINUTE) + ":" + gc.get(Calendar.SECOND));
if (gc.isLeapYear(gc.get(Calendar.YEAR)))
System.out.println("當前年份是閏年");
else
System.out.println("當前年份不是閏年");
舊 API (Date、Calendar) 存在可變性、非執行緒安全、設計混亂等問題。Java 8 引入 java.time:
LocalDate、LocalTime、LocalDateTime:不可變、無時區ZonedDateTime、OffsetDateTime:帶時區Instant:時間戳記DateTimeFormatter:執行緒安全格式化Period、Duration:日期/時間間隔新專案強烈建議使用 java.time,舊代碼維護時可透過 toInstant()、Date.from() 互轉。