舊 API (java.util.Date, Calendar, SimpleDateFormat) 痛點:可變、非線程安全、月份從 0 開始、年份從 1900 起、時區處理混亂。Java 8 引入 java.time 包,**不可變、線程安全、領域模型清晰** (Instant, LocalDate, LocalTime, LocalDateTime, ZonedDateTime, Duration, Period)。
| 類 | 用途 | 例子 |
|---|---|---|
| Instant | 時間戳 (UTC) | 2024-01-14T08:30:00Z |
| LocalDate | 無時間日期 | 2024-01-14 |
| LocalTime | 無日期時間 | 16:30:00.123 |
| LocalDateTime | 日期時間 (無時區) | 2024-01-14T16:30:00.123 |
| ZonedDateTime | 帶時區完整時間 | 2024-01-14T16:30+08:00[Asia/Shanghai] |
| Duration | 時間間隔 (秒/納秒) | PT2H30M |
| Period | 日期間隔 (年/月/日) | P1Y2M10D |
LocalDate today = LocalDate.now(); // 2024-01-14
int year = today.getYear(); // 2024
int month = today.getMonthValue(); // 1
int day = today.getDayOfMonth(); // 14
LocalDate birth = LocalDate.of(2010, 1, 14); // 無月份 0 陷阱
if (today.equals(birth)) System.out.println("生日快樂!");
MonthDay birthMd = MonthDay.from(birth);
if (MonthDay.from(today).equals(birthMd)) System.out.println("Happy Birthday!");
LocalTime now = LocalTime.now(); // 16:33:33.369
LocalTime later = now.plusHours(2); // 18:33:33.369
LocalDate nextWeek = today.plus(1, ChronoUnit.WEEKS); // 2024-01-21
LocalDate nextMonth = today.plusMonths(1);
LocalDate lastYear = today.minus(1, ChronoUnit.YEARS);
LocalDate nextYear = today.plusYears(1);
Clock clock = Clock.system(ZoneId.of("Asia/Shanghai"));
LocalDate now = LocalDate.now(clock);
LocalDate tomorrow = today.plusDays(1);
if (tomorrow.isAfter(today)) System.out.println("明天在今天之後");
ZoneId ny = ZoneId.of("America/New_York");
ZonedDateTime zdt = ZonedDateTime.now(ny); // 紐約當前時間
YearMonth ym = YearMonth.of(2025, 2);
int days = ym.lengthOfMonth(); // 28 或 29,自動判斷閏年
if (today.isLeapYear()) System.out.println("閏年");
Period p = Period.between(today, LocalDate.of(2024, 3, 14));
System.out.println(p.getMonths()); // 2 月
OffsetDateTime odt = LocalDateTime.of(2024,1,14,19,30)
.atOffset(ZoneOffset.of("+05:30")); // 印度時間
Instant now = Instant.now(); // 2024-01-14T08:33:33.379Z
Date legacy = Date.from(now); // 舊 API 互轉
LocalDate d = LocalDate.parse("20240116", DateTimeFormatter.BASIC_ISO_DATE);
DateTimeFormatter fmt = DateTimeFormatter.ofPattern("MMM dd yyyy");
LocalDate holiday = LocalDate.parse("Apr 18 2024", fmt);
String formatted = LocalDateTime.now().format(
DateTimeFormatter.ofPattern("MMM dd yyyy hh:mm a")); // Jan 14 2024 04:33 PM
LocalDate/LocalTime/LocalDateTime,無時區業務勿用 ZonedDateTime。DateTimeFormatter 線程安全,可定義為 static final 常量複用。MM月 mm分,HH24時 hh12時。新 API 將時間領域知識內化為類設計,用好它,告別時間處理噩夢!