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

Java SimpleDateFormat 實現「年-月-日 上午/下午 時:分:秒」日期格式化

     編輯:Java 相關知識

Java 日期格式化常見需求:將 Date 轉為「yyyy-MM-dd 上午/下午 hh:mm:ss」格式。本文提供最簡潔的 SimpleDateFormat 範例,並補充 **執行緒安全問題**、**Java 8 新 API 替代方案**與 **時區/語系陷阱**避坑指南。

核心程式碼(Java 7/8 通用)

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

public class DateFormatDemo {
    public static void main(String[] args) {
        // a 代表 AM/PM 標記,hh 為 12 小時制
        String pattern = "yyyy-MM-dd a hh:mm:ss";
        SimpleDateFormat sdf = new SimpleDateFormat(pattern, Locale.getDefault()); // 明確指定 Locale
        System.out.println(sdf.format(new Date()));
        // 輸出範例:2024-05-20 下午 03:45:12
    }
}

常用格式符號對照表

符號含義範例
yyyy年(4 位)2024
MM月(2 位)05
dd日(2 位)20
aAM/PM 標記上午/下午
hh12 小時制(01-12)03
HH24 小時制(00-23)15
mm分45
ss秒12
E星期幾週一

⚠️ 重大坑點:SimpleDateFormat 非執行緒安全

SimpleDateFormat 為**有狀態**類別,多執行緒共用同一實例會導致格式錯誤或拋出異常。

  • 錯誤寫法: static final SimpleDateFormat SDF = new SimpleDateFormat(...); 共用。
  • 正確寫法 1(ThreadLocal):
private static final ThreadLocal<SimpleDateFormat> TL_SDF = ThreadLocal.withInitial(() ->
    new SimpleDateFormat("yyyy-MM-dd a hh:mm:ss", Locale.getDefault()));
public static String format(Date date) { return TL_SDF.get().format(date); }
  • 正確寫法 2(每次新建,簡單場景可接受): new SimpleDateFormat(pattern).format(date)
  • 正確寫法 3(Java 8+ 推薦): 使用不可變、執行緒安全的 DateTimeFormatter。

Java 8+ 現代寫法(強烈推薦)

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.ZoneId;

public class ModernDateFormat {
    private static final DateTimeFormatter FORMATTER =
        DateTimeFormatter.ofPattern("yyyy-MM-dd a hh:mm:ss", Locale.getDefault());

    public static String formatNow() {
        return LocalDateTime.now(ZoneId.systemDefault()).format(FORMATTER);
    }

    public static String format(Date date) {
        return date.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime().format(FORMATTER);
    }
}
  • DateTimeFormatter **不可變、執行緒安全**、效能更好、API 更豐富(解析/格式化分離)。
  • 支援 ZoneId 精確控制時區,避免預設時區導致的跨日錯誤。

語系陷阱:AM/PM 顯示語言

a 標記輸出語言取決於 Locale:

  • Locale.CHINA / Locale.TAIWAN → 「上午/下午」
  • Locale.US → 「AM/PM」
  • **最佳實踐:明確指定 Locale**,避免伺服器預設語系導致輸出不一致。

總結建議

  • ✅ 新專案**直接使用 Java 8 DateTimeFormatter**。
  • ✅ 維舊專案若必須用 SimpleDateFormat,採用 ThreadLocal 或每次新建。
  • ✅ 格式化時**明確指定 Locale 與 ZoneId**。
  • ✅ 避免在高併發熱點路徑頻繁建立格式化物件,改用快取或物件池。

正確處理日期格式化,是避免生產環境離奇 Bug 的關鍵細節。

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