Skip to content

LocalDate / LocalTime / LocalDateTime

JDK 8+ 日期时间 API 概览

终于!Java 在 JDK 8 带来了全新的日期时间 API,设计清晰、线程安全、使用方便。

核心思想很简单:按职责分离

LocalDate    → 只管「哪一天」
LocalTime    → 只管「几点几分几秒」
LocalDateTime → 日期 + 时间都有了

LocalDate:只关心日期

创建

java
// 当前日期
LocalDate today = LocalDate.now();
System.out.println(today); // 2026-03-22

// 指定日期
LocalDate birthday = LocalDate.of(2026, 3, 22);
LocalDate birthday2 = LocalDate.of(2026, Month.MARCH, 22);

// 从字符串解析
LocalDate parsed = LocalDate.parse("2026-03-22");
LocalDate parsed2 = LocalDate.parse("2026/03/22",
    DateTimeFormatter.ofPattern("yyyy/MM/dd"));

获取字段

java
LocalDate date = LocalDate.now();

date.getYear();           // 2026
date.getMonth();          // MARCH(Month 类型)
date.getMonthValue();    // 3(int)
date.getDayOfMonth();    // 22
date.getDayOfWeek();      // SUNDAY(DayOfWeek 类型)
date.getDayOfYear();     // 81(一年中第几天)
date.lengthOfMonth();     // 31(本月的天数)
date.lengthOfYear();      // 365 或 366

计算

java
LocalDate date = LocalDate.now();

// 加减
date.plusDays(7);           // 7 天后
date.minusDays(1);          // 昨天
date.plusWeeks(1);          // 一周后
date.plusMonths(1);         // 一个月后
date.plusYears(1);          // 一年后

// 特殊计算
date.withDayOfMonth(1);     // 月初
date.with(TemporalAdjusters.lastDayOfMonth()); // 月末
date.with(TemporalAdjusters.firstDayOfMonth()); // 月初
date.with(TemporalAdjusters.next(DayOfWeek.MONDAY)); // 下周一
date.with(TemporalAdjusters.previous(DayOfWeek.FRIDAY)); // 上周五

// 判断
date.isLeapYear();          // 是否闰年
date.isAfter(LocalDate.of(2026, 1, 1)); // 是否在...之后
date.isBefore(LocalDate.of(2026, 12, 31)); // 是否在...之前
date.isEqual(LocalDate.of(2026, 3, 22)); // 是否相等

LocalTime:只关心时间

创建

java
// 当前时间
LocalTime now = LocalTime.now();
System.out.println(now); // 14:30:45.123

// 指定时间
LocalTime time = LocalTime.of(14, 30);
LocalTime time2 = LocalTime.of(14, 30, 45);
LocalTime time3 = LocalTime.of(14, 30, 45, 123_000_000);

// 从字符串解析
LocalTime parsed = LocalTime.parse("14:30:45");

获取字段

java
LocalTime time = LocalTime.now();

time.getHour();    // 14
time.getMinute();  // 30
time.getSecond();  // 45
time.getNano();    // 123000000

计算

java
LocalTime time = LocalTime.now();

time.plusHours(1);     // 1 小时后
time.plusMinutes(30); // 30 分钟后
time.minusSeconds(10); // 10 秒前

LocalDateTime:日期时间合体

创建

java
// 当前时间
LocalDateTime now = LocalDateTime.now();

// 指定日期时间
LocalDateTime dt = LocalDateTime.of(2026, 3, 22, 14, 30);
LocalDateTime dt2 = LocalDateTime.of(date, time);

// 组合
LocalDate date = LocalDate.now();
LocalTime time = LocalTime.now();
LocalDateTime combined = LocalDateTime.of(date, time);

// 从 LocalDate + LocalTime
LocalDateTime fromParts = date.atTime(time);
LocalDateTime fromParts2 = time.atDate(date);

// 转换
dt.toLocalDate(); // → LocalDate
dt.toLocalTime(); // → LocalTime

计算

java
LocalDateTime dt = LocalDateTime.now();

dt.plusDays(1);              // 明天
dt.minusHours(1);            // 1 小时前
dt.withMinute(0);            // 整点
dt.withSecond(0);            // 去掉秒

格式化与解析

java
LocalDateTime dt = LocalDateTime.now();

// 格式化
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
String formatted = dt.format(formatter); // 2026-03-22 14:30:00

// 解析
LocalDateTime parsed = LocalDateTime.parse("2026-03-22 14:30:00", formatter);

// 常用格式
DateTimeFormatter.ISO_LOCAL_DATE;          // 2026-03-22
DateTimeFormatter.ISO_LOCAL_TIME;           // 14:30:45
DateTimeFormatter.ISO_LOCAL_DATE_TIME;      // 2026-03-22T14:30:45
DateTimeFormatter.ofPattern("yyyy年MM月dd日 HH:mm"); // 2026年03月22日 14:30

实际应用

计算年龄

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

int age = calculateAge(LocalDate.of(2000, 3, 22));

判断工作日

java
public static boolean isWorkday(LocalDate date) {
    DayOfWeek dow = date.getDayOfWeek();
    return dow != DayOfWeek.SATURDAY && dow != DayOfWeek.SUNDAY;
}

月初到月末

java
LocalDate today = LocalDate.now();

LocalDate monthStart = today.withDayOfMonth(1);
LocalDate monthEnd = today.with(TemporalAdjusters.lastDayOfMonth());

时间段计算

java
LocalDateTime start = LocalDateTime.of(2026, 1, 1, 0, 0);
LocalDateTime end = LocalDateTime.now();

Duration duration = Duration.between(start, end);
System.out.println("天数: " + duration.toDays());
System.out.println("小时: " + duration.toHours());
System.out.println("分钟: " + duration.toMinutes());

总结

职责示例
LocalDate只管日期2026-03-22
LocalTime只管时间14:30:45
LocalDateTime日期+时间2026-03-22 14:30:45
Instant时间戳1709454645.123
Duration时间段(时分秒)PT1H30M
Period日期间段P1M5D

记住:

  • 不可变:所有方法返回新实例,原实例不变
  • 线程安全:可以放心在多线程中使用
  • API 清晰:LocalDate 只管日期,LocalTime 只管时间

基于 VitePress 构建