1. LocalDate: 沒有時間與時區的日期
LocalDate 就是單純的日期。沒有時間、沒有時區、不添麻煩。就像日曆上的一頁:2025-06-01——就這樣。如果你不在意不同城市的「午夜」何時,只需要「2025 年 6 月 1 日」——請使用 LocalDate。
如何建立 LocalDate?
有幾種方式,都很簡單又好用。
目前日期
import java.time.LocalDate;
LocalDate today = LocalDate.now();
System.out.println(today); // 例如,2025-06-01
指定日期
LocalDate birthday = LocalDate.of(1990, 12, 15);
System.out.println(birthday); // 1990-12-15
可以用數字指定年、月、日。月份是從 1 到 12(一月是 1,十二月是 12)。
從字串解析
LocalDate parsedDate = LocalDate.parse("2025-06-01");
System.out.println(parsedDate); // 2025-06-01
字串必須是 yyyy-MM-dd 格式。若格式不符合,會拋出例外。
取得日期的各個部分
LocalDate 有一些方法能回傳日期的各個部分:
int year = today.getYear(); // 2025
int month = today.getMonthValue(); // 6(六月)
int day = today.getDayOfMonth(); // 1
System.out.println("年:" + year + ",月:" + month + ",日:" + day);
如果想用文字取得月份,請使用 getMonth() 方法:
System.out.println(today.getMonth()); // JUNE
如果需要星期幾——使用 getDayOfWeek() 方法:
System.out.println(today.getDayOfWeek()); // SATURDAY
實用範例
繼續擴充你的學習用主控台應用:現在它可以在生日向使用者致意。
import java.time.LocalDate;
public class BirthdayApp {
public static void main(String[] args) {
LocalDate birthday = LocalDate.of(2000, 2, 29);
System.out.println("生日日期:" + birthday);
System.out.println("生日是星期幾:" + birthday.getDayOfWeek());
}
}
2. LocalTime: 沒有日期與時區的時間
LocalTime 就是時間:時、分、秒(甚至奈秒),但沒有日期!如果只需要保存「商店開門時間」或「會議開始時間」而不綁定日期——這就是你要的類別。
如何建立 LocalTime?
目前時間
import java.time.LocalTime;
LocalTime now = LocalTime.now();
System.out.println(now); // 例如,14:37:12.123456789
指定時間
LocalTime lunchTime = LocalTime.of(13, 30); // 13:30:00
System.out.println(lunchTime);
也可以加入秒與奈秒:
LocalTime precise = LocalTime.of(8, 15, 30, 123_000_000); // 08:15:30.123
System.out.println(precise);
從字串解析
LocalTime parsedTime = LocalTime.parse("14:30:00");
System.out.println(parsedTime); // 14:30
取得時間的各個部分
int hour = now.getHour();
int minute = now.getMinute();
int second = now.getSecond();
System.out.println("小時:" + hour + ",分鐘:" + minute + ",秒:" + second);
實用範例
為我們的應用程式加上「時鐘」:
import java.time.LocalTime;
public class ClockApp {
public static void main(String[] args) {
LocalTime current = LocalTime.now();
System.out.println("現在:" + current);
System.out.println("小時:" + current.getHour());
System.out.println("分鐘:" + current.getMinute());
}
}
3. LocalDateTime: 沒有時區的日期與時間
LocalDateTime 是組合:日期 + 時間,但仍然沒有時區。例如「2025-06-01 14:30:00」。這很適合在你想保存某個時刻、但不在意讀取它的人位於地球上哪裡時使用。
如何建立 LocalDateTime?
目前的日期與時間
import java.time.LocalDateTime;
LocalDateTime now = LocalDateTime.now();
System.out.println(now); // 例如,2025-06-01T14:30:15.123456789
指定的日期與時間
LocalDateTime meeting = LocalDateTime.of(2025, 6, 1, 14, 30);
System.out.println(meeting); // 2025-06-01T14:30
也可以加入秒與奈秒:
LocalDateTime preciseMeeting = LocalDateTime.of(2025, 6, 1, 14, 30, 45, 123_000_000);
System.out.println(preciseMeeting); // 2025-06-01T14:30:45.123
從字串解析
LocalDateTime parsed = LocalDateTime.parse("2025-06-01T14:30:00");
System.out.println(parsed); // 2025-06-01T14:30
請注意:依照 ISO 標準,字母 T 用來分隔日期與時間。
取得各個組件
int year = now.getYear();
int month = now.getMonthValue();
int day = now.getDayOfMonth();
int hour = now.getHour();
int minute = now.getMinute();
System.out.println("日期:" + year + "-" + month + "-" + day + " 時間:" + hour + ":" + minute);
4. 日期與時間的常見操作
既然我們會建立日期與時間物件了,接下來學些有用的操作吧。
加減運算
這三個類別(LocalDate、LocalTime、LocalDateTime)都是不可變的。也就是說,像 plusDays() 或 minusMonths() 這類方法都會回傳新物件,而不會修改原本的物件。
LocalDate
LocalDate today = LocalDate.now();
LocalDate tomorrow = today.plusDays(1);
LocalDate lastMonth = today.minusMonths(1);
System.out.println("今天:" + today);
System.out.println("明天:" + tomorrow);
System.out.println("一個月前:" + lastMonth);
LocalTime
LocalTime now = LocalTime.now();
LocalTime inTenMinutes = now.plusMinutes(10);
System.out.println("現在:" + now);
System.out.println("10 分鐘後:" + inTenMinutes);
LocalDateTime
LocalDateTime start = LocalDateTime.of(2025, 6, 1, 14, 0);
LocalDateTime end = start.plusHours(2).minusMinutes(15);
System.out.println("開始:" + start);
System.out.println("結束:" + end);
比較日期與時間
所有類別都具有 isBefore()、isAfter()、isEqual() 方法:
LocalDate birthday = LocalDate.of(2000, 2, 29);
LocalDate today = LocalDate.now();
if (today.isAfter(birthday)) {
System.out.println("你比剛出生還要年長!");
}
LocalTime morning = LocalTime.of(8, 0);
LocalTime now = LocalTime.now();
if (now.isBefore(morning)) {
System.out.println("現在起床還太早……");
} else {
System.out.println("該起床了!");
}
取得目前日期/時間
如你所見,now() 方法會回傳當前的值:
LocalDate date = LocalDate.now();
LocalTime time = LocalTime.now();
LocalDateTime dateTime = LocalDateTime.now();
5. 實作:範例與練習
範例 1:任意日期是星期幾
import java.time.LocalDate;
public class DayOfWeekApp {
public static void main(String[] args) {
LocalDate anyDate = LocalDate.of(2025, 12, 31);
System.out.println("2025 年 12 月 31 日是 " + anyDate.getDayOfWeek());
}
}
範例 2:距離新年還有幾天?
import java.time.LocalDate;
import java.time.temporal.ChronoUnit;
public class DaysToNewYear {
public static void main(String[] args) {
LocalDate today = LocalDate.now();
LocalDate newYear = LocalDate.of(today.getYear() + 1, 1, 1);
long daysLeft = ChronoUnit.DAYS.between(today, newYear);
System.out.println("離新年還有 " + daysLeft + " 天!");
}
}
範例 3:判斷是否為閏年
import java.time.LocalDate;
public class LeapYearCheck {
public static void main(String[] args) {
LocalDate date = LocalDate.of(2025, 1, 1);
if (date.isLeapYear()) {
System.out.println(date.getYear() + " 是閏年!");
} else {
System.out.println(date.getYear() + " 是平年。");
}
}
}
範例 4:兩個時間點的差距
import java.time.LocalTime;
import java.time.Duration;
public class TimeDifference {
public static void main(String[] args) {
LocalTime start = LocalTime.of(9, 0);
LocalTime end = LocalTime.of(17, 30);
Duration duration = Duration.between(start, end);
System.out.println("工時長度為 " + duration.toHours() + " 小時 " +
(duration.toMinutes() % 60) + " 分鐘。");
}
}
6. 常見錯誤
錯誤 1:混淆 LocalDateTime 與 ZonedDateTime。
LocalDateTime 不包含任何時區資訊!如果你要保存跨國航班時刻或在不同時區發生的事件——請使用 ZonedDateTime,否則在系統間搬移資料時可能會得到意想不到的結果。
錯誤 2:使用了錯誤的字串格式來解析。
例如,嘗試用 LocalDate.parse() 解析 01.06.2025。預設期望的格式是 2025-06-01。其他格式需要專用的 DateTimeFormatter(下一講會說明!)。
錯誤 3:以為 plusDays() 這類方法會修改物件。
不會!所有物件都是不可變的。方法會回傳新物件,舊的保持不變。
錯誤 4:用 LocalTime 來保存絕對時間。
LocalTime 只代表一天中的本地時間。如果你想保存「時間點」,請使用 Instant 或 ZonedDateTime。
錯誤 5:忘了月份的編號差異(1 是一月,12 是十二月)。
在 LocalDate.of(year, month, day) 中,月份是從 1 開始(而不是從 0 開始,和某些其他語言或舊 API 不同)。
GO TO FULL VERSION