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

Java 日期時間格式化完全指南:SimpleDateFormat 詳解

     編輯:Java 相關知識

掌握 SimpleDateFormat:從基礎模式到線程安全陷阱

日期時間格式化是 Java 開發的高頻需求。SimpleDateFormat 作為最常用的格式化工具,功能強大但也存在著名的線程不安全問題。本文全面解析其用法、模式字母、常見陷阱及現代替代方案。

基本用法

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;

public class DateFormatTest {
    public static void main(String[] args) {
        // 注意:String 不要寫成 Strings
        DateFormat df = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
        Date currentTime = new Date();
        String currentTimedf = df.format(currentTime);
        System.out.println("現在時間是: " + currentTimedf);
    }
}

模式字母完整對照表

字母含義示例備註
y年2024 / 24yyyy=4位,yy=2位
M月07 / Jul / JulyMM=兩位,MMM=縮寫,MMMM=全稱
d月中的天05 / 5
H一天中的小時 (0-23)1424小時制
h上午/下午中的小時 (1-12)0212小時制
m小時中的分鐘30
s分鐘中的秒45
S毫秒123SSS=三位毫秒
E星期幾週二 / Tuesday
aAM/PM 標記PM
z時區名稱CST / GMT+08:00
Z時區偏移量+0800RFC 822 格式
XISO 8601 時區+08:00 / ZJava 7+

常見格式模式範例

SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");     // 2024-01-15 14:30:45
SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd");              // 2024/01/15
SimpleDateFormat sdf = new SimpleDateFormat("yyyy年M月d日 E HH:mm");    // 2024年1月15日 週一 14:30
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssXXX"); // 2024-01-15T14:30:45+08:00 (ISO 8601)
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");          // 20240115143045 (文件名時間戳)

⚠️ 關鍵陷阱:線程不安全

SimpleDateFormat 是線程不安全的! 多線程共享同一實例會導致格式化結果錯誤、拋出異常甚至數據損壞。

錯誤示例:

// 危險!多線程環境下共享實例
public class UnsafeDateFormat {
    private static final SimpleDateFormat SDF = new SimpleDateFormat("yyyy-MM-dd");
    
    public String format(Date date) {
        return SDF.format(date); // 併發調用會出錯
    }
}

正確解決方案:

// 方案 1:局部變量(推薦簡單場景)
public String format(Date date) {
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
    return sdf.format(date);
}

// 方案 2:ThreadLocal(高併發場景)
public class SafeDateFormat {
    private static final ThreadLocal SDF_THREAD_LOCAL = 
        ThreadLocal.withInitial(() -> new SimpleDateFormat("yyyy-MM-dd"));
    
    public String format(Date date) {
        return SDF_THREAD_LOCAL.get().format(date);
    }
}

// 方案 3:Java 8+ DateTimeFormatter(現代標準,線程安全)
import java.time.format.DateTimeFormatter;
import java.time.LocalDateTime;

public class ModernDateFormat {
    private static final DateTimeFormatter FORMATTER = 
        DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
    
    public String format(LocalDateTime dateTime) {
        return FORMATTER.format(dateTime); // 線程安全!
    }
}

解析字符串為 Date

SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
try {
    Date date = sdf.parse("2024-01-15 14:30:45");
    System.out.println(date);
} catch (ParseException e) {
    e.printStackTrace();
}

遷移建議:擁抱 Java 8 Time API

新項目強烈建議使用 java.time 包:

  • LocalDate、LocalTime、LocalDateTime - 不帶時區
  • ZonedDateTime、OffsetDateTime - 帶時區
  • DateTimeFormatter - 線程安全的格式化器
  • Instant - 時間戳(替代 Date)
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved