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

Java 日期與字符串互轉完全指南:SimpleDateFormat 模式、解析異常、線程安全與最佳實踐

     編輯:Java 綜合教學

Java 日期與字符串互轉完全指南:SimpleDateFormat 模式、解析異常、線程安全與最佳實踐

Web 開發中,前端傳遞字符串日期,後端需解析為 Date 存入數據庫;查詢時再格式化為字符串返回前端。SimpleDateFormat 是 JDK 7 及之前的標準工具,但存在線程不安全、模式匹配嚴格等坑點,本文系統總結。

核心類結構

  • DateFormat:抽象父類,定義 format(Date)/parse(String)。
  • SimpleDateFormat:具體實現,支持自定義模式。
  • FastDateFormat (Apache Commons Lang):線程安全、不可變,推薦替代。

常用模式字母

字母含義示例
y年yyyy=2024, yy=24
M月MM=01, M=1
d日dd=01, d=1
H時 (0-23)HH=13, H=13
h時 (1-12)hh=01, h=1
m分mm=05, m=5
s秒ss=09, s=9
S毫秒SSS=123
E星期EEE=Mon, EEEE=Monday
z時區GMT+08:00
ZRFC 822 時區+0800
XISO 8601 時區+08:00, +0800, Z

日期 → 字符串 (格式化)

Date date = new Date();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
System.out.println(sdf.format(date)); // 2024-01-15

sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
System.out.println(sdf.format(date)); // 2024-01-15 14:30:45

sdf = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
System.out.println(sdf.format(date)); // 2024年01月15日 14:30:45

字符串 → 日期 (解析)

String str = "2024-01-15 14:30:45";
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date date = sdf.parse(str); // 拋 ParseException,需 try-catch

模式匹配規則與常見異常

輸入字符串模式結果說明
2024-01-15 14:30:45yyyy-MM-dd HH:mm:ss✅ 成功完全匹配
2024-01-15yyyy-MM-dd HH:mm:ss❌ ParseException字符串缺少時分秒,模式要求完整
2024-01-15 14:30:45yyyy-MM-dd✅ 成功 (時分秒為 0)模式比字符串短,多餘部分忽略
2024/01/15yyyy-MM-dd❌ ParseException分隔符不匹配

規則:解析時,字符串必須包含模式要求的所有字段;模式可比字符串短 (忽略尾部),不能比字符串長 (缺字段報錯)。

線程安全陷阱與解決方案

SimpleDateFormat 非線程安全:內部 Calendar 實例共享,併發調用 format/parse 會導致數據錯亂、拋 ArrayIndexOutOfBoundsException 或結果錯誤。

方案對比

方案代碼優點缺點
方法局部變量new SimpleDateFormat(...)簡單、絕對安全頻繁創建對象,GC 壓力
ThreadLocal 緩存ThreadLocal.withInitial(() -> new SimpleDateFormat(...))復用實例、線程隔離代碼較繁瑣、內存洩漏風險 (線程池)
FastDateFormat (推薦)FastDateFormat.getInstance("yyyy-MM-dd")線程安全、不可變、高性能、單例需引入 commons-lang3
DateTimeFormatter (JDK 8+)DateTimeFormatter.ofPattern(...)標準庫、線程安全、不可變、功能豐富需遷移至 java.time 類型

空值/異常防禦編程

// 判空比較:推薦模式
if (str == null || str.trim().isEmpty()) return null;
try {
    return sdf.parse(str);
} catch (ParseException e) {
    log.warn("日期解析失敗: {}", str, e);
    return null; // 或拋業務異常
}

最佳實踐清單

  1. 項目統一使用 FastDateFormat (JDK 7) 或 DateTimeFormatter (JDK 8+),禁用 SimpleDateFormat 實例共享。
  2. 定義常量模式字符串,避免硬編碼分散:DATE_PATTERN = "yyyy-MM-dd"。
  3. 解析前預處理:去除空格、統一分隔符、補齊零寬字段。
  4. 數據庫存儲統一用 UTC 時間戳 (BIGINT) 或 TIMESTAMP WITH TIME ZONE,展示層按用戶時區格式化。
  5. 序列化框架 (Jackson/Fastjson) 配置統一日期格式,避免雙向轉換不一致。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved