String.format() 配合 %t 前綴提供了強大的日期時間格式化能力,且原生支援 Locale 多語系輸出。不同於 SimpleDateFormat 需實例化模式字串,String.format 採用類 C 的格式化語法,程式碼更簡潔、可讀性更高。本文詳細說明常用模式字元、Locale 影響與實戰範例。
String formatted = String.format(locale, formatString, dateArgument);
Locale.US、Locale.TAIWAN),預設為系統預設 Locale。%tX 模式字元,X 為具體格式代碼。java.util.Date、Calendar、Long(毫秒時間戳)或 TemporalAccessor 實作。| 代碼 | 說明 | 範例 (Locale.US) | 範例 (Locale.TAIWAN) |
|---|---|---|---|
%tY | 四位數年份 | 2024 | 2024 |
%ty | 兩位數年份 | 24 | 24 |
%tB | 月份全名 | January | 一月 |
%tb | 月份縮寫 | Jan | 1月 |
%tm | 兩位數月份 | 01 | 01 |
%td | 兩位數日期 | 15 | 15 |
%te | 日期(不補零) | 15 | 15 |
%tA | 星期全名 | Monday | 星期一 |
%ta | 星期縮寫 | Mon | 週一 |
%tH | 24小時制時(00-23) | 14 | 14 |
%tI | 12小時制時(01-12) | 02 | 02 |
%tM | 分鐘(00-59) | 30 | 30 |
%tS | 秒數(00-59) | 45 | 45 |
%tp | AM/PM 標記 | PM | 下午 |
%tR | 時間 %tH:%tM | 14:30 | 14:30 |
%tT | 時間 %tH:%tM:%tS | 14:30:45 | 14:30:45 |
%tc | 完整日期時間 %ta %tb %td %tT %tZ %tY | Mon Jan 15 14:30:45 CST 2024 | 週一 1月 15 14:30:45 CST 2024 |
%tF | ISO 日期 %tY-%tm-%td | 2024-01-15 | 2024-01-15 |
%tD | 美式日期 %tm/%td/%ty | 01/15/24 | 01/15/24 |
import java.util.Date;
import java.util.Locale;
public class DateFormatDemo {
public static void main(String[] args) {
Date now = new Date();
System.out.println("=== 基本日期元件 ===");
System.out.printf(Locale.US, "年份(4位): %tY%n", now);
System.out.printf(Locale.US, "年份(2位): %ty%n", now);
System.out.printf(Locale.US, "月份全名: %tB%n", now);
System.out.printf(Locale.US, "月份縮寫: %tb%n", now);
System.out.printf(Locale.US, "月份(2位): %tm%n", now);
System.out.printf(Locale.US, "日期(2位): %td%n", now);
System.out.printf(Locale.US, "日期(不補零): %te%n", now);
System.out.println("\n=== 星期資訊 ===");
System.out.printf(Locale.US, "星期全名: %tA%n", now);
System.out.printf(Locale.US, "星期縮寫: %ta%n", now);
System.out.printf(Locale.TAIWAN, "繁體中文星期: %tA%n", now);
System.out.printf(Locale.TAIWAN, "繁體中文縮寫: %ta%n", now);
System.out.println("\n=== 時間元件 ===");
System.out.printf("24小時制: %tH%n", now);
System.out.printf("12小時制: %tI%n", now);
System.out.printf("分鐘: %tM%n", now);
System.out.printf("秒數: %tS%n", now);
System.out.printf("AM/PM: %tp%n", now);
System.out.println("\n=== 組合格式 ===");
System.out.printf("ISO 日期: %tF%n", now); // 2024-01-15
System.out.printf("美式日期: %tD%n", now); // 01/15/24
System.out.printf("時間 HH:MM: %tR%n", now); // 14:30
System.out.printf("時間 HH:MM:SS: %tT%n", now); // 14:30:45
System.out.printf("完整日期時間: %tc%n", now); // Mon Jan 15 14:30:45 CST 2024
System.out.println("\n=== 自訂組合:中文完整日期 ===");
String chineseDate = String.format(Locale.TAIWAN, "%tY年%tm月%td日 %tA", now, now, now, now);
System.out.println(chineseDate); // 2024年01月15日 星期一
}
}
格式字串中可用 %1$tY、%1$tm 等引用同一個日期參數,避免重複傳遞:
String custom = String.format(Locale.TAIWAN, "%1$tY年%1$tm月%1$td日 %1$tA", now);
// 2024年01月15日 星期一
無需建立 Date 物件,直接傳入 long 毫秒數:
long ts = System.currentTimeMillis();
String iso = String.format("%tF %tT", ts, ts); // 2024-01-15 14:30:45
Calendar / ZonedDateTimeCalendar cal = Calendar.getInstance();
System.out.printf("%tF", cal); // 支援
// Java 8+ TemporalAccessor
ZonedDateTime zdt = ZonedDateTime.now();
System.out.printf("%tF %tT", zdt, zdt); // 支援
String.format 內部使用 Formatter,每次呼叫建立新實例,天然執行緒安全,優於 SimpleDateFormat。DateTimeFormatter(Java 8+)並預編譯,效能提升 3-5 倍。NullPointerException,請改用 Locale.getDefault() 或明確指定。%te 與 %td 差異:前者不補零(1-31),後者補零(01-31),中文環境下輸出相同但英文環境下 %te 可能含前導空格。String.format() 的日期格式化語法簡潔且功能完整,特別適合:
對於複雜解析、高效能序列化、時區運算等進階場景,請優先使用 Java 8+ java.time 套件(DateTimeFormatter、ZonedDateTime 等)。