首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 程式設計入門

Java 日期格式化完全指南:DateFormat 風格與模式詳解

     編輯:Java 程式設計入門

Java 早期 java.util.Date + java.text.DateFormat 組合雖被 Java 8 java.time 取代,但在維護舊系統、Android 開發、快速腳本場景仍廣泛使用。本文系統梳理 DateFormat 四大預設風格、自定義模式、線程安全陷阱及現代替代方案。

四大預設風格對比

import java.util.*;
import java.text.*;

public class DateStyleDemo {
    public static void main(String[] args) {
        Date now = new Date();
        
        DateFormat dfDefault = DateFormat.getDateInstance();           // DEFAULT
        DateFormat dfShort   = DateFormat.getDateInstance(DateFormat.SHORT);
        DateFormat dfMedium  = DateFormat.getDateInstance(DateFormat.MEDIUM);
        DateFormat dfLong    = DateFormat.getDateInstance(DateFormat.LONG);
        DateFormat dfFull    = DateFormat.getDateInstance(DateFormat.FULL);
        
        System.out.println("(DEFAULT) " + dfDefault.format(now));
        System.out.println("(SHORT)   " + dfShort.format(now));
        System.out.println("(MEDIUM)  " + dfMedium.format(now));
        System.out.println("(LONG)    " + dfLong.format(now));
        System.out.println("(FULL)    " + dfFull.format(now));
    }
}

輸出示例 (Locale=US, 时区=GMT+8)

風格輸出示例適用場景
SHORT12/31/23緊湊顯示、表格列、日誌時間戳
MEDIUMDec 31, 2023通用業務顯示、報表、郵件
LONGDecember 31, 2023正式文檔、合同、證書
FULLSunday, December 31, 2023用戶通知、行程單、完整語境

關鍵點:輸出深度依賴 Locale。中文環境下:SHORT=23-12-31、MEDIUM=2023年12月31日、LONG=2023年12月31日、FULL=2023年12月31日 星期日。

自定義模式:SimpleDateFormat 完全掌控

SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS z");
System.out.println(sdf.format(now)); // 2023-12-31 23:59:59.123 CST

常用模式字母速查

字母含義示例
y年2023, 23
M月12, Dec, December
d月中的日31
H小時 (0-23)23
h小時 (1-12)11
m分鐘59
s秒59
S毫秒123
E星期幾Sun, Sunday
z時區名CST, GMT+08:00
Z時區偏移+0800

重複字母控制長度:MM=02、MMM=Dec、MMMM=December。

⚠️ 致命陷阱:非線程安全

// 錯誤示範:靜態共享實例
private static final SimpleDateFormat SDF = new SimpleDateFormat("yyyy-MM-dd");

// 多線程併發調用 SDF.format() 會導致數據錯亂、甚至拋 ArrayIndexOutOfBoundsException

解決方案

  1. ThreadLocal 緩存(高性能、兼容舊代碼)
  2. 每次 new 實例(簡單、低併發可接受)
  3. Java 8+ DateTimeFormatter(不可變、線程安全、首選)
// ThreadLocal 方案
private static final ThreadLocal TL_SDF = ThreadLocal.withInitial(
    () -> new SimpleDateFormat("yyyy-MM-dd")
);
public static String format(Date date) {
    return TL_SDF.get().format(date);
}

現代替代:Java 8 java.time 包

import java.time.*;
import java.time.format.*;

LocalDateTime now = LocalDateTime.now();
DateTimeFormatter fmt = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
System.out.println(now.format(fmt)); // 線程安全、不可變、功能更強
舊 API新 API (java.time)優勢
DateInstant / LocalDateTime / ZonedDateTime不可變、清晰語義、納秒精度
CalendarZonedDateTime / OffsetDateTime時區處理正確、流式 API
DateFormatDateTimeFormatter線程安全、預編譯、解析更嚴格
SimpleDateFormatDateTimeFormatter.ofPattern()同左

最佳實踐清單

  1. 新項目強制使用 java.time
  2. 舊代碼維護:SimpleDateFormat 必須用 ThreadLocal 或局部變量
  3. 序列化傳輸:統一用 ISO-8601 ( yyyy-MM-dd'T'HH:mm:ss.SSSXXX )
  4. 資料庫交互:JDBC 4.2+ 直接支持 LocalDateTime、OffsetDateTime
  5. 時區敏感業務:務必用 ZonedDateTime,避免 Date 隱含默認時區陷阱

告別 SimpleDateFormat 線程安全噩夢,擁抱 java.time 的清晰與安全。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved