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

JDK 8 新日期時間 API (java.time) 實戰範例大全

     編輯:Java 相關知識

核心類別速覽

類別用途特點
LocalDate日期 (年月日)無時區、不可變
LocalTime時間 (時分秒)無時區、不可變
LocalDateTime日期時間無時區、不可變
ZonedDateTime帶時區日期時間含 ZoneId、DST 自動處理
Instant時間戳 (UTC)機器時間、ナノ秒精度
Period日期量 (年月日)人類概念
Duration時間量 (時分秒)機器概念

完整操作範例


import java.time.*;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.time.temporal.TemporalAdjusters;
import java.util.Locale;

public class DateTimeDemo {
    public static void main(String[] args) {
        // 1. 取得當前
        LocalDateTime now = LocalDateTime.now();
        System.out.println("現在: " + now); // 2024-05-20T14:30:00.123

        // 2. 建構指定時間
        LocalDate date = LocalDate.of(2024, Month.DECEMBER, 25);
        LocalTime time = LocalTime.of(23, 59, 59);
        LocalDateTime dt = LocalDateTime.of(date, time);
        System.out.println("聖誕夜: " + dt);

        // 3. 解析字串
        LocalTime parsedTime = LocalTime.parse("13:37", DateTimeFormatter.ofPattern("HH:mm"));
        LocalDate parsedDate = LocalDate.parse("2024-12-25", DateTimeFormatter.ISO_LOCAL_DATE);

        // 4. 取得欄位
        System.out.println("年: " + now.getYear());
        System.out.println("月: " + now.getMonth()); // MAY
        System.out.println("日: " + now.getDayOfMonth());
        System.out.println("星期: " + now.getDayOfWeek()); // MONDAY
        System.out.println("秒: " + now.getSecond());

        // 5. 時間運算 (回傳新物件,原物件不變)
        LocalDateTime future = now.plusWeeks(2).plusHours(3).minusMinutes(30);
        LocalDateTime past = now.minus(Period.ofDays(10));
        System.out.println("兩周後: " + future);

        // 6. TemporalAdjusters 進階調整
        System.out.println("本月最後一天: " + now.with(TemporalAdjusters.lastDayOfMonth()));
        System.out.println("下個週三: " + now.with(TemporalAdjusters.next(DayOfWeek.WEDNESDAY)));
        System.out.println("本月第一個週五: " + now.with(TemporalAdjusters.dayOfWeekInMonth(1, DayOfWeek.FRIDAY)));

        // 7. 截斷精度
        System.out.println("截至分鐘: " + now.truncatedTo(ChronoUnit.MINUTES));
        System.out.println("截至秒: " + now.truncatedTo(ChronoUnit.SECONDS));

        // 8. 時區轉換
        ZonedDateTime taipei = now.atZone(ZoneId.of("Asia/Taipei"));
        ZonedDateTime utc = taipei.withZoneSameInstant(ZoneOffset.UTC);
        System.out.println("台北: " + taipei);
        System.out.println("UTC: " + utc);

        // 9. OffsetTime (固定偏移)
        OffsetTime offsetTime = OffsetTime.now();
        OffsetTime tokyo = offsetTime.withOffsetSameInstant(ZoneOffset.of("+09:00"));
        System.out.println("東京時間: " + tokyo);

        // 10. 期間與持續時間
        Period period = Period.of(1, 2, 3); // 1年2月3日
        Duration duration = Duration.ofHours(5).plusMinutes(30);
        System.out.println("加上期間: " + now.plus(period));
        System.out.println("加上持續: " + now.plus(duration));

        // 11. 兩時間差
        Duration between = Duration.between(
            ZonedDateTime.now(ZoneId.of("Asia/Taipei")),
            ZonedDateTime.now(ZoneOffset.UTC)
        );
        System.out.println("時差: " + between.toHours() + " 小時");

        // 12. 格式化輸出 (執行緒安全)
        DateTimeFormatter fmt = DateTimeFormatter.ofPattern("yyyy年MM月dd日 HH:mm:ss", Locale.TRADITIONAL_CHINESE);
        System.out.println("中文格式: " + now.format(fmt));
    }
}

關鍵最佳實踐

  1. 優先用 LocalDate/LocalTime/LocalDateTime:無時區、不可變、執行緒安全、效能最好。
  2. 跨時區業務必用 ZonedDateTime:自動處理夏令時間 (DST),ZoneId.of("Asia/Taipei") 而非固定偏移。
  3. 持久化存 Instant (UTC):資料庫存 TIMESTAMP WITH TIME ZONE 或 BIGINT (epoch milliseconds),顯示時轉換使用者時區。
  4. DateTimeFormatter 可重用、執行緒安全:宣告為 static final 常數,避免 SimpleDateFormat 非執行緒安全的坑。
  5. 期間用 Period,持續時間用 Duration:Period.between(date1, date2) 算年月日,Duration.between(instant1, instant2) 算時分秒。

遷移舊代碼對照表

舊 API (java.util / java.sql)新 API (java.time)轉換方式
new Date()Instant.now()Date.from(instant) / instant.atZone(zone).toLocalDateTime()
Calendar.getInstance()LocalDateTime.now() / ZonedDateTime.now()calendar.toInstant()
SimpleDateFormatDateTimeFormatterformatter.format(temporal) / formatter.parse(str)
TimeZone.getTimeZone("GMT+8")ZoneId.of("Asia/Taipei")zoneId.getRules()
GregorianCalendarZonedDateTimegcal.toZonedDateTime()

總結

JDK 8 java.time 以**不可變、領域驅動、執行緒安全**三大特性,徹底解決舊 API 易誤用、難國際化、效能差的痛點。新專案全面採用,舊專案逐步遷移,享受現代化時間處理體驗。

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