Java LocalDate

LocalDate 是 Java 8 引入的日期類別,用於表示不含時間的日期(年、月、日),位於 java.time 套件中。

引入套件

import java.time.LocalDate;

建立 LocalDate

取得當前日期

LocalDate today = LocalDate.now();
System.out.println(today);  // 2024-12-10

指定日期

// of(年, 月, 日)
LocalDate date1 = LocalDate.of(2024, 12, 25);
System.out.println(date1);  // 2024-12-25

// 使用 Month 列舉
LocalDate date2 = LocalDate.of(2024, Month.DECEMBER, 25);
System.out.println(date2);  // 2024-12-25

從字串解析

LocalDate date = LocalDate.parse("2024-12-25");
System.out.println(date);  // 2024-12-25

// 自訂格式
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy/MM/dd");
LocalDate date2 = LocalDate.parse("2024/12/25", formatter);
System.out.println(date2);  // 2024-12-25

取得日期資訊

LocalDate date = LocalDate.of(2024, 12, 25);

// 取得年、月、日
int year = date.getYear();           // 2024
int month = date.getMonthValue();    // 12
Month monthEnum = date.getMonth();   // DECEMBER
int day = date.getDayOfMonth();      // 25

// 取得星期幾
DayOfWeek dayOfWeek = date.getDayOfWeek();  // WEDNESDAY
int dayValue = dayOfWeek.getValue();         // 3 (週一=1, 週日=7)

// 取得該年的第幾天
int dayOfYear = date.getDayOfYear();  // 360

// 取得該月天數
int lengthOfMonth = date.lengthOfMonth();  // 31

// 取得該年天數
int lengthOfYear = date.lengthOfYear();  // 366 (閏年)

// 判斷是否為閏年
boolean isLeap = date.isLeapYear();  // true

日期運算

加減日期

LocalDate date = LocalDate.of(2024, 12, 25);

// 加上天數
LocalDate plus3Days = date.plusDays(3);      // 2024-12-28
LocalDate plus2Weeks = date.plusWeeks(2);    // 2025-01-08
LocalDate plus1Month = date.plusMonths(1);   // 2025-01-25
LocalDate plus1Year = date.plusYears(1);     // 2025-12-25

// 減去天數
LocalDate minus5Days = date.minusDays(5);    // 2024-12-20
LocalDate minus1Month = date.minusMonths(1); // 2024-11-25

使用 Period

LocalDate date = LocalDate.of(2024, 12, 25);
Period period = Period.ofMonths(2);

LocalDate newDate = date.plus(period);  // 2025-02-25

修改日期

LocalDate date = LocalDate.of(2024, 12, 25);

// 設定特定值
LocalDate newYear = date.withYear(2025);       // 2025-12-25
LocalDate newMonth = date.withMonth(6);        // 2024-06-25
LocalDate newDay = date.withDayOfMonth(1);     // 2024-12-01
LocalDate newDayOfYear = date.withDayOfYear(1); // 2024-01-01

日期比較

LocalDate date1 = LocalDate.of(2024, 12, 25);
LocalDate date2 = LocalDate.of(2024, 12, 31);

// 比較方法
boolean isBefore = date1.isBefore(date2);  // true
boolean isAfter = date1.isAfter(date2);    // false
boolean isEqual = date1.isEqual(date2);    // false

// compareTo
int result = date1.compareTo(date2);  // 負數(date1 較早)

計算日期差距

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

// 使用 Period
Period period = Period.between(start, end);
System.out.println(period.getYears());   // 0
System.out.println(period.getMonths());  // 11
System.out.println(period.getDays());    // 30

// 使用 ChronoUnit 計算總天數
long days = ChronoUnit.DAYS.between(start, end);     // 365
long weeks = ChronoUnit.WEEKS.between(start, end);   // 52
long months = ChronoUnit.MONTHS.between(start, end); // 11

時間調節器 (TemporalAdjuster)

import java.time.temporal.TemporalAdjusters;

LocalDate date = LocalDate.of(2024, 12, 15);

// 該月第一天
LocalDate firstDay = date.with(TemporalAdjusters.firstDayOfMonth());  // 2024-12-01

// 該月最後一天
LocalDate lastDay = date.with(TemporalAdjusters.lastDayOfMonth());    // 2024-12-31

// 下一年第一天
LocalDate nextYear = date.with(TemporalAdjusters.firstDayOfNextYear()); // 2025-01-01

// 下一個星期一
LocalDate nextMonday = date.with(TemporalAdjusters.next(DayOfWeek.MONDAY)); // 2024-12-16

// 該月第三個星期五
LocalDate thirdFriday = date.with(TemporalAdjusters.dayOfWeekInMonth(3, DayOfWeek.FRIDAY)); // 2024-12-20

格式化輸出

LocalDate date = LocalDate.of(2024, 12, 25);

// 預設格式
System.out.println(date.toString());  // 2024-12-25

// 自訂格式
DateTimeFormatter formatter1 = DateTimeFormatter.ofPattern("yyyy/MM/dd");
System.out.println(date.format(formatter1));  // 2024/12/25

DateTimeFormatter formatter2 = DateTimeFormatter.ofPattern("yyyy年MM月dd日");
System.out.println(date.format(formatter2));  // 2024年12月25日

DateTimeFormatter formatter3 = DateTimeFormatter.ofPattern("MM-dd-yyyy");
System.out.println(date.format(formatter3));  // 12-25-2024

轉換為其他類型

LocalDate date = LocalDate.of(2024, 12, 25);

// 轉換為 LocalDateTime(加上時間)
LocalDateTime dateTime = date.atStartOfDay();  // 2024-12-25T00:00
LocalDateTime dateTime2 = date.atTime(14, 30); // 2024-12-25T14:30

// 轉換為 ZonedDateTime
ZonedDateTime zdt = date.atStartOfDay(ZoneId.of("Asia/Taipei"));

// 轉換為 Epoch Day(從 1970-01-01 起的天數)
long epochDay = date.toEpochDay();  // 20082

實用範例

計算年齡

public static int calculateAge(LocalDate birthDate) {
    LocalDate today = LocalDate.now();
    return Period.between(birthDate, today).getYears();
}

LocalDate birthday = LocalDate.of(1990, 5, 15);
System.out.println("年齡: " + calculateAge(birthday));

判斷是否為週末

public static boolean isWeekend(LocalDate date) {
    DayOfWeek day = date.getDayOfWeek();
    return day == DayOfWeek.SATURDAY || day == DayOfWeek.SUNDAY;
}

LocalDate date = LocalDate.of(2024, 12, 28);
System.out.println(isWeekend(date));  // true (星期六)

取得某月所有日期

public static List<LocalDate> getAllDatesInMonth(int year, int month) {
    List<LocalDate> dates = new ArrayList<>();
    LocalDate start = LocalDate.of(year, month, 1);
    LocalDate end = start.with(TemporalAdjusters.lastDayOfMonth());
    
    while (!start.isAfter(end)) {
        dates.add(start);
        start = start.plusDays(1);
    }
    return dates;
}

重點整理

  • LocalDate 表示不含時間的日期
  • 不可變(immutable)類別,所有運算都回傳新物件
  • 使用 now() 取得當前日期
  • 使用 of() 建立指定日期
  • 使用 plus/minus 方法進行日期運算
  • 使用 isBefore/isAfter 比較日期
  • 搭配 DateTimeFormatter 格式化輸出