Java 日期時間

Java 8 引入了新的日期時間 API (java.time),比舊的 DateCalendar 更好用。

主要類別

類別說明
LocalDate日期(年月日)
LocalTime時間(時分秒)
LocalDateTime日期和時間
ZonedDateTime帶時區的日期時間
Instant時間戳記
Duration時間間隔
Period日期間隔

LocalDate

只包含日期:

import java.time.LocalDate;

// 取得今天
LocalDate today = LocalDate.now();  // 2024-12-10

// 指定日期
LocalDate date = LocalDate.of(2024, 12, 25);

// 解析字串
LocalDate parsed = LocalDate.parse("2024-12-25");

// 取得資訊
int year = today.getYear();           // 2024
int month = today.getMonthValue();    // 12
int day = today.getDayOfMonth();      // 10
DayOfWeek dow = today.getDayOfWeek(); // TUESDAY

// 日期計算
LocalDate tomorrow = today.plusDays(1);
LocalDate lastMonth = today.minusMonths(1);
LocalDate nextYear = today.plusYears(1);

// 比較
today.isBefore(tomorrow);  // true
today.isAfter(tomorrow);   // false
today.isEqual(today);      // true

詳細說明:LocalDate

LocalTime

只包含時間:

import java.time.LocalTime;

// 取得現在時間
LocalTime now = LocalTime.now();  // 14:30:45.123

// 指定時間
LocalTime time = LocalTime.of(14, 30, 45);

// 取得資訊
int hour = now.getHour();
int minute = now.getMinute();
int second = now.getSecond();

// 時間計算
LocalTime later = now.plusHours(2);
LocalTime earlier = now.minusMinutes(30);

詳細說明:LocalTime

LocalDateTime

包含日期和時間:

import java.time.LocalDateTime;

// 現在
LocalDateTime now = LocalDateTime.now();

// 指定日期時間
LocalDateTime dt = LocalDateTime.of(2024, 12, 25, 10, 30, 0);

// 從 LocalDate 和 LocalTime 組合
LocalDate date = LocalDate.of(2024, 12, 25);
LocalTime time = LocalTime.of(10, 30);
LocalDateTime combined = LocalDateTime.of(date, time);

// 取得日期或時間部分
LocalDate datePart = now.toLocalDate();
LocalTime timePart = now.toLocalTime();

詳細說明:LocalDateTime

DateTimeFormatter

格式化和解析:

import java.time.format.DateTimeFormatter;

LocalDateTime now = LocalDateTime.now();

// 預設格式化器
DateTimeFormatter iso = DateTimeFormatter.ISO_LOCAL_DATE_TIME;
String isoStr = now.format(iso);  // 2024-12-10T14:30:45

// 自訂格式
DateTimeFormatter custom = DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss");
String customStr = now.format(custom);  // 2024/12/10 14:30:45

// 解析
LocalDateTime parsed = LocalDateTime.parse("2024/12/25 10:30:00", custom);

// 常用格式
DateTimeFormatter.ofPattern("yyyy-MM-dd");           // 2024-12-10
DateTimeFormatter.ofPattern("MM/dd/yyyy");           // 12/10/2024
DateTimeFormatter.ofPattern("yyyy年MM月dd日");        // 2024年12月10日
DateTimeFormatter.ofPattern("HH:mm:ss");             // 14:30:45
DateTimeFormatter.ofPattern("a hh:mm");              // 下午 02:30

詳細說明:DateTimeFormatter

Duration 和 Period

Duration(時間間隔)

import java.time.Duration;

LocalTime start = LocalTime.of(9, 0);
LocalTime end = LocalTime.of(17, 30);

Duration duration = Duration.between(start, end);
System.out.println(duration.toHours());    // 8
System.out.println(duration.toMinutes());  // 510

// 建立
Duration hours = Duration.ofHours(5);
Duration minutes = Duration.ofMinutes(30);

Period(日期間隔)

import java.time.Period;

LocalDate start = LocalDate.of(2020, 1, 1);
LocalDate end = LocalDate.of(2024, 12, 10);

Period period = Period.between(start, end);
System.out.println(period.getYears());   // 4
System.out.println(period.getMonths());  // 11
System.out.println(period.getDays());    // 9

詳細說明:Duration 和 Period

ZonedDateTime

帶時區的日期時間:

import java.time.ZonedDateTime;
import java.time.ZoneId;

// 當前時區
ZonedDateTime now = ZonedDateTime.now();

// 指定時區
ZonedDateTime tokyo = ZonedDateTime.now(ZoneId.of("Asia/Tokyo"));
ZonedDateTime utc = ZonedDateTime.now(ZoneId.of("UTC"));

// 轉換時區
ZonedDateTime taipei = now.withZoneSameInstant(ZoneId.of("Asia/Taipei"));

詳細說明:ZonedDateTime

Instant

時間戳記(UTC):

import java.time.Instant;

Instant now = Instant.now();
long epochSecond = now.getEpochSecond();
long epochMilli = now.toEpochMilli();

// 從時間戳記建立
Instant instant = Instant.ofEpochMilli(System.currentTimeMillis());

詳細說明:Instant

實際應用

計算年齡

LocalDate birthday = LocalDate.of(1990, 5, 15);
LocalDate today = LocalDate.now();

int age = Period.between(birthday, today).getYears();

計算工作天

LocalDate start = LocalDate.of(2024, 12, 1);
LocalDate end = LocalDate.of(2024, 12, 31);

long workDays = start.datesUntil(end)
    .filter(d -> d.getDayOfWeek() != DayOfWeek.SATURDAY)
    .filter(d -> d.getDayOfWeek() != DayOfWeek.SUNDAY)
    .count();

每月第一天/最後一天

LocalDate today = LocalDate.now();
LocalDate firstDay = today.withDayOfMonth(1);
LocalDate lastDay = today.with(TemporalAdjusters.lastDayOfMonth());