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

Java 日期時間處理大全:從 Calendar 到 Date、格式化、計算、轉換、數據庫映射一網打盡

     編輯:Java 相關知識

核心類速查

  • java.util.Date:時間戳(毫秒精度),多數方法已過時。
  • java.util.Calendar:抽象基類,GregorianCalendar 為具體實現,支援字段操作與國際化。
  • java.text.SimpleDateFormat:格式化/解析,非線程安全。
  • java.sql.Date、Time、Timestamp:JDBC 專用,對應數據庫 DATE/TIME/DATETIME。

高頻操作代碼模板

1. 獲取某月最大天數

Calendar cal = Calendar.getInstance();
cal.clear(); // 必須先 clear,否則繼承系統當前時間殘留字段
cal.set(Calendar.YEAR, year);
cal.set(Calendar.MONTH, month - 1); // 月份 0-based
int days = cal.getActualMaximum(Calendar.DAY_OF_MONTH);

2. Calendar ⇄ Date 雙向轉換

// Calendar → Date
Date date = cal.getTime();
// Date → Calendar
Calendar cal = Calendar.getInstance();
cal.setTime(date);

3. 格式化輸出(最常用)

SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String formatted = sdf.format(new Date()); // 2024-05-18 14:30:00
// 解析
Date parsed = sdf.parse("2024-05-18 14:30:00");

4. 計算一年中的第幾周 / 第幾周的日期

// 某日是第幾周
cal.set(2024, Calendar.MAY, 18);
int weekOfYear = cal.get(Calendar.WEEK_OF_YEAR);

// 第 N 周的周一日期
cal.set(2024, Calendar.JANUARY, 1);
cal.set(Calendar.WEEK_OF_YEAR, n);
cal.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);

5. add() vs roll()

  • add(field, amount):正規加減,會進位(如 8/31 + 1 天 = 9/1)。
  • roll(field, amount):本字段循環,不進位(8/31 roll 1 天 = 8/1)。

6. 精確計算兩日期間隔天數

// 推薦:基於 Calendar DAY_OF_YEAR 與年份差累加,避免 DST 導致的毫秒法誤差
public int getDaysBetween(Calendar d1, Calendar d2) {
    if (d1.after(d2)) { Calendar tmp = d1; d1 = d2; d2 = tmp; }
    int days = d2.get(Calendar.DAY_OF_YEAR) - d1.get(Calendar.DAY_OF_YEAR);
    int y2 = d2.get(Calendar.YEAR);
    if (d1.get(Calendar.YEAR) != y2) {
        d1 = (Calendar) d1.clone();
        do {
            days += d1.getActualMaximum(Calendar.DAY_OF_YEAR);
            d1.add(Calendar.YEAR, 1);
        } while (d1.get(Calendar.YEAR) != y2);
    }
    return days;
}

7. String ⇄ Date ⇄ Long 三向轉換

// String → Date → Long
SimpleDateFormat sdf = new SimpleDateFormat("M/dd/yyyy hh:mm:ss a", Locale.US);
Date d = sdf.parse("5/13/2003 10:31:37 AM");
long ts = d.getTime();

// Long → Date → String
SimpleDateFormat out = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String str = out.format(new Date(ts));

8. 日期推算:年月周 → 具體日期、判斷星期幾

// "2003-05 5 星期五" → 具體日期
SimpleDateFormat f = new SimpleDateFormat("yyyy-MM w E");
Date d = f.parse("2003-05 5 星期五");

// 判斷星期
SimpleDateFormat wf = new SimpleDateFormat("E");
String week = wf.format(date); // "週二"

9. JDBC 日期類型映射

數據庫類型Java 類型適用場景
Oracle DATEjava.sql.Date僅需年月日
SQL Server DATETIMEjava.sql.Timestamp需年月日時分秒毫秒
MySQL DATETIMEjava.sql.Timestamp同左
// 通用字符串 → Timestamp
public static Timestamp string2Time(String s) throws ParseException {
    SimpleDateFormat f = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS", Locale.ENGLISH);
    f.setLenient(false);
    return new Timestamp(f.parse(s).getTime());
}
// 通用字符串 → java.sql.Date
public static java.sql.Date string2Date(String s) throws ParseException {
    SimpleDateFormat f = new SimpleDateFormat("yyyy-MM-dd", Locale.ENGLISH);
    f.setLenient(false);
    return new java.sql.Date(f.parse(s).getTime());
}

避坑指南

  • 月份陷阱:Calendar.MONTH 0=1月,11=12月。
  • 線程安全:SimpleDateFormat 非線程安全,請使用 ThreadLocal 或 Java 8+ DateTimeFormatter。
  • 時區:跨時區應用務必顯式設定 TimeZone,避免夏令時導致日期偏移。
  • Lenient 模式:解析嚴格格式時調用 setLenient(false),防止「2024-02-30」被自動糾正為 3/1。

掌握這套模板,應對 90% 以上的 Java 日期時間業務場景綽綽有餘。

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