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

Java 取得當前日期時間兩大方式:Date/Calendar 與 Java 8 新 API 對比

     編輯:Java 相關知識

方式一:傳統 Date + Calendar (JDK 1.0/1.1)

⚠️ **缺點**:可變、非執行緒安全、月份 0-based、年份偏移 1900、API 設計混亂。僅維護舊代碼時使用。


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

public class LegacyDateTime {
    public static void main(String[] args) {
        // 1. Date 取得當前
        Date now = new Date();
        System.out.println("Date.toString(): " + now); // Mon May 20 14:30:00 CST 2024

        // 2. DateFormat 格式化 (非執行緒安全!)
        DateFormat df1 = DateFormat.getDateInstance();           // 短日期
        DateFormat df2 = DateFormat.getDateTimeInstance();       // 日期時間
        DateFormat df3 = DateFormat.getTimeInstance();           // 時間
        DateFormat df4 = DateFormat.getInstance();               // 短日期時間
        System.out.println("預設日期: " + df1.format(now));
        System.out.println("預設日期時間: " + df2.format(now));
        System.out.println("預設時間: " + df3.format(now));
        System.out.println("短格式: " + df4.format(now));

        // 3. 自訂格式 (SimpleDateFormat 非執行緒安全)
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        System.out.println("自訂: " + sdf.format(now));

        // 4. Calendar 取得欄位 (月份 0-based!)
        Calendar cal = Calendar.getInstance();
        int year = cal.get(Calendar.YEAR);
        int month = cal.get(Calendar.MONTH) + 1; // +1 修正
        int day = cal.get(Calendar.DAY_OF_MONTH);
        int hour = cal.get(Calendar.HOUR_OF_DAY); // 24制
        int min = cal.get(Calendar.MINUTE);
        int sec = cal.get(Calendar.SECOND);
        System.out.printf("Calendar: %d-%02d-%02d %02d:%02d:%02d%n", year, month, day, hour, min, sec);
    }
}

方式二:Java 8 java.time (現代標準,強烈推薦)

✅ **優點**:不可變、執行緒安全、領域驅動設計、月份 1-based、納秒精度、支援時區/DST。


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

public class ModernDateTime {
    public static void main(String[] args) {
        // 1. 核心類別取得當前
        LocalDate date = LocalDate.now();           // 2024-05-20
        LocalTime time = LocalTime.now();           // 14:30:00.123
        LocalDateTime dt = LocalDateTime.now();     // 2024-05-20T14:30:00.123
        ZonedDateTime zdt = ZonedDateTime.now();    // 2024-05-20T14:30:00.123+08:00[Asia/Taipei]
        Instant instant = Instant.now();            // 2024-05-20T06:30:00.123Z (UTC)

        // 2. 取得欄位 (直觀、無偏移)
        System.out.println("年: " + dt.getYear());
        System.out.println("月: " + dt.getMonthValue()); // 5
        System.out.println("日: " + dt.getDayOfMonth());
        System.out.println("時: " + dt.getHour());
        System.out.println("分: " + dt.getMinute());
        System.out.println("秒: " + dt.getSecond());

        // 3. 格式化 (DateTimeFormatter 執行緒安全,可重用)
        DateTimeFormatter fmt = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        System.out.println("格式化: " + dt.format(fmt));

        // 4. 解析
        LocalDateTime parsed = LocalDateTime.parse("2024-12-31 23:59:59", fmt);

        // 5. 互相轉換
        Instant ins = dt.atZone(ZoneId.systemDefault()).toInstant();
        Date legacy = Date.from(ins); // 轉舊 Date
        System.out.println("轉 Date: " + legacy);
    }
}

核心差異對照表

特性Date/Calendarjava.time
可變性可變 (setTime, add)不可變 (plus/minus 回傳新物件)
執行緒安全❌ SimpleDateFormat 非安全✅ 全部安全
月份索引0-11 (坑)1-12 (直觀)
年份基準1900 (getYear() 已棄用)實際年份
精度毫秒納秒
時區處理TimeZone 混亂ZoneId/ZoneOffset 清晰
格式化類別SimpleDateFormat (非安全)DateTimeFormatter (安全)

遷移速查表

舊代碼新代碼
new Date()Instant.now() / LocalDateTime.now()
Calendar.getInstance()LocalDateTime.now() / ZonedDateTime.now()
new SimpleDateFormat("...")DateTimeFormatter.ofPattern("...")
date.getTime()instant.toEpochMilli()
cal.get(Calendar.MONTH)+1localDate.getMonthValue()
cal.add(Calendar.DAY, 1)localDate.plusDays(1)

最佳實踐建議

  1. 新專案 100% 使用 java.time:零理由用舊 API。
  2. 資料庫儲存 Instant (UTC):`TIMESTAMP WITH TIME ZONE` 或 `BIGINT` 毫秒數。
  3. 顯示層依使用者時區轉換:`zdt.withZoneSameInstant(userZone)`
  4. DateTimeFormatter 宣告為 static final:重用、執行緒安全。
  5. 舊代碼逐步遷移:邊界處 (Controller、Repository) 先轉換,核心域模型全面換新。

Java 8 日期時間 API 設計優雅、功能強大,徹底解決舊 API 三大痛點 (可變、非安全、月份偏移)。全面擁抱 `java.time`,享受現代化時間處理體驗。

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