`SimpleDateFormat` 是 Java 日期格式化與解析核心工具,掌握模式字母大小寫差異、執行緒不安全特性與現代替代方案,避免生產環境Bug。
| 字母 | 含義 | 範例 | 注意 |
|---|---|---|---|
| y | 年 | 2024 / 24 | yyyy=完整年,yy=兩位年 |
| M | 月 | 07 / Jul / July | MM=兩位數,MMM=縮寫,MMMM=全名 |
| d | 日 | 10 | |
| H | 時 (24制) | 19 | 0-23 |
| h | 時 (12制) | 07 | 1-12,需搭配 a (AM/PM) |
| m | 分 | 20 | 小寫 m! |
| s | 秒 | 00 | |
| S | 毫秒 | 123 | |
| a | AM/PM | PM | |
| Z | 時區偏移 | +0800 |
大小寫極其重要:`MM`=月,`mm`=分;`HH`=24制,`hh`=12制。
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
// 字串 → Date
String str = "2024-07-10 19:20:00";
Date date = sdf.parse(str);
// Date → 字串
String formatted = sdf.format(new Date());
// 輸出: 2024-07-10 19:20:00
// 自訂格式
SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy年MM月dd日");
System.out.println(sdf2.format(new Date()));
// 輸出: 2024年07月10日
import java.util.Date;
import java.text.ParseException;
import java.text.SimpleDateFormat;
public class DateConvertUtil {
private static final String DEFAULT_PATTERN = "yyyy-MM-dd HH:mm:ss";
public static String dateToStr(Date date) {
return dateToStr(date, DEFAULT_PATTERN);
}
public static String dateToStr(Date date, String pattern) {
if (date == null) return null;
return new SimpleDateFormat(pattern).format(date);
}
public static Date strToDate(String str) {
return strToDate(str, DEFAULT_PATTERN);
}
public static Date strToDate(String str, String pattern) {
if (str == null || str.trim().isEmpty()) return null;
try {
return new SimpleDateFormat(pattern).parse(str);
} catch (ParseException e) {
throw new IllegalArgumentException("日期解析失敗: " + str, e);
}
}
public static void main(String[] args) {
Date now = new Date();
System.out.println("日期轉字串: " + dateToStr(now));
System.out.println("字串轉日期: " + strToDate(dateToStr(now)));
}
}
錯誤做法:靜態共享實例
// 危險!多執行緒併發會導致解析錯誤、數據竄改
public static final SimpleDateFormat SDF = new SimpleDateFormat("yyyy-MM-dd");
正確做法三選一:
private static final ThreadLocal SDF_THREAD_LOCAL =
ThreadLocal.withInitial(() -> new SimpleDateFormat("yyyy-MM-dd"));
DateTimeFormatter fmt = DateTimeFormatter.ofPattern("yyyy-MM-dd");
LocalDate date = LocalDate.parse(str, fmt);
String out = date.format(fmt);
| 舊類別 | 新替代 | 優勢 |
|---|---|---|
| Date | Instant / LocalDate / LocalDateTime | 不可變、領域清晰 |
| Calendar | ZonedDateTime | 時區處理正確 |
| SimpleDateFormat | DateTimeFormatter | 執行緒安全、效能更好 |
新專案強烈建議直接使用 `java.time`,舊專案逐步遷移。