在開發跨時區應用時,正確獲取特定時區的當前時間是常見需求。本文將詳細介紹如何使用 Java 核心庫獲取美國洛杉磯時間,並對比上海時間展示時差。
以下是使用 SimpleDateFormat、Calendar 和 TimeZone 類獲取洛杉磯時間的完整示例:
SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
Calendar calendar = Calendar.getInstance();
// 設置時區為美國洛杉磯
sdf.setTimeZone(TimeZone.getTimeZone("America/Los_Angeles"));
System.out.println("Los_Angeles: " + sdf.format(calendar.getTime()));
// 切換至上海時區對比
sdf.setTimeZone(TimeZone.getTimeZone("Asia/Shanghai"));
System.out.println("Shanghai: " + sdf.format(calendar.getTime()));
Java 使用 IANA 時區數據庫標識符,常用的包括:
注意: SimpleDateFormat 不是線程安全的。在多線程環境下,建議使用以下替代方案:
// 方案一:使用 ThreadLocal
private static final ThreadLocal SDF_THREAD_LOCAL =
ThreadLocal.withInitial(() -> new SimpleDateFormat("yyyy/MM/dd HH:mm:ss"));
// 方案二:Java 8+ 使用 DateTimeFormatter(線程安全)
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss");
ZonedDateTime laTime = ZonedDateTime.now(ZoneId.of("America/Los_Angeles"));
System.out.println("Los_Angeles: " + laTime.format(formatter));
Java 8 引入了 java.time 包,提供更優雅、線程安全的時間處理:
import java.time.*;
import java.time.format.DateTimeFormatter;
public class TimeZoneDemo {
public static void main(String[] args) {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss");
// 獲取洛杉磯當前時間
ZonedDateTime laTime = ZonedDateTime.now(ZoneId.of("America/Los_Angeles"));
System.out.println("Los_Angeles: " + laTime.format(formatter));
// 獲取上海當前時間
ZonedDateTime shanghaiTime = ZonedDateTime.now(ZoneId.of("Asia/Shanghai"));
System.out.println("Shanghai: " + shanghaiTime.format(formatter));
// 計算時差
Duration diff = Duration.between(laTime.toInstant(), shanghaiTime.toInstant());
System.out.println("時差: " + diff.toHours() + " 小時");
}
}
使用 America/Los_Angeles 而非 PST 或 PDT,因為前者會自動根據日期切換標準時間/夏令時,後者固定不變。
DateTimeFormatter 實例(線程安全)Calendar 或 ZonedDateTime 對象ZoneId.of("America/Los_Angeles")獲取特定時區時間的核心在於正確設置 TimeZone 或 ZoneId。現代 Java 開發強烈建議使用 java.time 包,它解決了舊 API 的線程安全、設計缺陷等問題,代碼也更加直觀易維護。