java.util.TimeZone 代表時區偏移量與夏令時間規則。搭配 Date、Calendar 使用時,決定日期時間的「顯示」與「解析」行為。掌握 TimeZone 可避免跨時區系統的時間顯示錯誤。
TimeZone defaultTz = TimeZone.getDefault();
// 例:執行環境在台灣 → "Asia/Taipei" (GMT+08:00)
// 標準 GMT 格式
TimeZone gmt8 = TimeZone.getTimeZone("GMT+08:00");
// 區域型 ID(推薦,自動處理夏令時間)
TimeZone taipei = TimeZone.getTimeZone("Asia/Taipei");
TimeZone newYork = TimeZone.getTimeZone("America/New_York");
String[] ids = TimeZone.getAvailableIDs();
for (String id : ids) {
System.out.println(id);
}
// 輸出範例:Asia/Taipei, America/New_York, GMT+08:00, ...
亦可依偏移量(毫秒)篩選:
String[] ids = TimeZone.getAvailableIDs(8 * 3600 * 1000); // GMT+8 的所有 ID
| 方法 | 說明 |
|---|---|
getID() | 取得時區 ID(如 "Asia/Taipei") |
getDisplayName() | 取得本地化顯示名稱(如 "台北標準時間") |
getRawOffset() | 取得基礎偏移量(毫秒),不含夏令時間 |
getOffset(long date) | 取得指定時間點的總偏移量(含夏令時間) |
useDaylightTime() | 是否支援夏令時間 |
inDaylightTime(Date) | 指定日期是否在夏令時間期間 |
setRawOffset(int) | 設定基礎偏移量(罕用) |
clone() | 複製物件 |
public class TimeZoneDemo {
public static void main(String[] args) {
// 固定瞬間:2013-09-19 14:22:30 (預設時區)
Date date = new Date(113, 8, 19, 14, 22, 30); // 年份-1900, 月份0-based
DateFormat df = DateFormat.getInstance();
// 預設時區
printTime(date, df, TimeZone.getDefault());
// GMT+08:00
printTime(date, df, TimeZone.getTimeZone("GMT+08:00"));
// Asia/Chongqing (中國標準時間)
printTime(date, df, TimeZone.getTimeZone("Asia/Chongqing"));
}
static void printTime(Date date, DateFormat df, TimeZone tz) {
df.setTimeZone(tz);
System.out.printf("%-20s : %s%n", tz.getID(), df.format(date));
}
}
輸出(視執行環境預設時區而異):
Asia/Taipei : 2013/9/19 下午 2:22
GMT+08:00 : 2013/9/19 下午 2:22
Asia/Chongqing : 2013/9/19 下午 2:22
user.timezoneuser.country + java.home 推導GMTWindows 從登錄表讀取,Linux/Unix 從環境變數 TZ 讀取。
# 啟動參數指定
java -Duser.timezone=Asia/Taipei -jar app.jar
# 或程式碼早期設定(需在任何 Date/Calendar 使用前)
System.setProperty("user.timezone", "Asia/Taipei");
TimeZone.setDefault(TimeZone.getTimeZone("Asia/Taipei"));
DateFormat df = DateFormat.getDateTimeInstance();
df.setTimeZone(TimeZone.getTimeZone("America/New_York"));
String nyTime = df.format(new Date());
EST、CST 等有歧義,務必使用區域型 ID(如 America/New_York、Asia/Shanghai)。SimpleDateFormat 非執行緒安全,併發環境請用 ThreadLocal 或 Java 8 DateTimeFormatter。java.time 套件(ZoneId、ZonedDateTime),API 更完善、不可變、執行緒安全。掌握 TimeZone 的建立、查詢、偏移量計算與 JVM 預設機制,能有效解決跨時區顯示問題。現代專案請優先採用 Java 8 java.time,舊專案維護時請記得在啟動參數或程式碼早期明確設定 user.timezone,避免環境差異導致的時間 Bug。