在 Java 中獲取並格式化當前時間是基礎高頻操作。本文介紹 java.util.Date 與 java.text.SimpleDateFormat 的經典組合,並補充現代 java.time API(Java 8+)的最佳實踐。
import java.util.Date;
import java.text.SimpleDateFormat;
public class NowString {
public static void main(String[] args) {
// 線程不安全!多線程環境下請使用 ThreadLocal 或 DateTimeFormatter
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
System.out.println(df.format(new Date())); // 輸出如:2024-03-15 14:30:45
}
}
| 字母 | 含義 | 示例 |
|---|---|---|
y | 年 | 2024 / 24 |
M | 月 | 03 / 3 / Mar / March |
d | 日 | 15 |
H | 時(24制) | 14 |
h | 時(12制) | 02 |
m | 分 | 30 |
s | 秒 | 45 |
S | 毫秒 | 123 |
E | 星期 | 週五 |
a | AM/PM | PM |
z | 時區 | CST / GMT+08:00 |
SimpleDateFormat 非線程安全。多線程共享實例會導致解析錯誤或數據競爭。解決方案:
ThreadLocal<SimpleDateFormat> 緩存java.time APIimport java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.ZoneId;
import java.util.Date;
public class ModernTime {
public static void main(String[] args) {
// 1. 獲取當前時間(不可變、線程安全)
LocalDateTime now = LocalDateTime.now();
System.out.println("默認格式: " + now); // 2024-03-15T14:30:45.123
// 2. 自定義格式(線程安全,可共享)
DateTimeFormatter fmt = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
System.out.println("格式化: " + now.format(fmt)); // 2024-03-15 14:30:45
// 3. 解析字符串
LocalDateTime parsed = LocalDateTime.parse("2024-01-01 00:00:00", fmt);
// 4. 與舊 API 互操作
Date legacyDate = Date.from(now.atZone(ZoneId.systemDefault()).toInstant());
LocalDateTime converted = legacyDate.toInstant()
.atZone(ZoneId.systemDefault())
.toLocalDateTime();
}
}
| 類 | 用途 | 特點 |
|---|---|---|
LocalDateTime | 日期時間(無時區) | 最常用,不可變 |
LocalDate | 僅日期 | 生日、節假日 |
LocalTime | 僅時間 | 鬧鐘、營業時間 |
ZonedDateTime | 帶時區日期時間 | 跨時區業務 |
Instant | 時間戳(納秒精度) | 日誌、持久化、傳輸 |
DateTimeFormatter | 格式化/解析 | 線程安全,可共享單例 |
java.time,API 設計更清晰、線程安全、功能豐富。ThreadLocal<SimpleDateFormat> 包裝舊 API。yyyy-MM-dd'T'HH:mm:ss.SSSXXX)或時間戳(Instant.toEpochMilli())。