Skip to content

LocalDateTime

LocalDateTime 是 JDK 8 日期时间 API 的核心类,把日期(LocalDate)和时间(LocalTime)组合在一起。

三个时间类

┌──────────────────────────────────────────────────────────────┐
│              JDK 8 日期时间三剑客                                │
├──────────────────────────────────────────────────────────────┤
│                                                              │
│  LocalDate     - 只有日期(年月日)                            │
│  LocalTime     - 只有时间(时分秒)                           │
│  LocalDateTime - 日期 + 时间                                   │
│                                                              │
│  ZonedDateTime - 带时区的日期时间                              │
│  Instant      - 时间戳(UTC)                                 │
│                                                              │
└──────────────────────────────────────────────────────────────┘

创建 LocalDateTime

java
import java.time.*;

// 当前时间
LocalDateTime now = LocalDateTime.now();
System.out.println(now);  // 2024-01-15T14:30:45

// 指定日期时间
LocalDateTime dt1 = LocalDateTime.of(2024, 1, 15, 14, 30);
LocalDateTime dt2 = LocalDateTime.of(2024, 1, 15, 14, 30, 45, 123_000_000);

// 从 LocalDate 和 LocalTime 组合
LocalDate date = LocalDate.of(2024, 1, 15);
LocalTime time = LocalTime.of(14, 30);
LocalDateTime dt3 = LocalDateTime.of(date, time);

常用操作

加减日期时间

java
LocalDateTime dt = LocalDateTime.of(2024, 1, 15, 14, 30);

// 加
dt.plusYears(1);      // 2025-01-15T14:30
dt.plusMonths(2);      // 2024-03-15T14:30
dt.plusDays(10);       // 2024-01-25T14:30
dt.plusHours(3);       // 2024-01-15T17:30
dt.plusMinutes(30);   // 2024-01-15T15:00

// 减
dt.minusWeeks(1);     // 2024-01-08T14:30
dt.minusSeconds(60);  // 2024-01-15T14:29

// 也可以直接修改
LocalDateTime tomorrow = dt.plusDays(1);

获取组件

java
LocalDateTime dt = LocalDateTime.of(2024, 3, 15, 14, 30, 45);

dt.getYear();          // 2024
dt.getMonth();         // MARCH(Month 枚举)
dt.getMonthValue();    // 3(int)
dt.getDayOfMonth();    // 15
dt.getDayOfWeek();     // FRIDAY(DayOfWeek 枚举)
dt.getDayOfYear();    // 75(第75天)

dt.getHour();          // 14
dt.getMinute();        // 30
dt.getSecond();        // 45
dt.getNano();         // 0(纳秒)

转换为其他类型

java
LocalDateTime dt = LocalDateTime.of(2024, 3, 15, 14, 30);

// 转 LocalDate
LocalDate date = dt.toLocalDate();  // 2024-03-15

// 转 LocalTime
LocalTime time = dt.toLocalTime();  // 14:30

// 转 Instant(UTC 时间戳)
Instant instant = dt.toInstant(ZoneOffset.UTC);

// 转 ZonedDateTime
ZonedDateTime zdt = dt.atZone(ZoneId.of("Asia/Shanghai"));

从其他类型转换

java
// 从 LocalDate + LocalTime
LocalDate date = LocalDate.of(2024, 3, 15);
LocalTime time = LocalTime.of(14, 30);
LocalDateTime dt = date.atTime(time);
LocalDateTime dt2 = time.atDate(date);

// 从 Instant
Instant instant = Instant.now();
LocalDateTime dt3 = LocalDateTime.ofInstant(instant, ZoneId.systemDefault());

比较

java
LocalDateTime dt1 = LocalDateTime.of(2024, 1, 15, 10, 0);
LocalDateTime dt2 = LocalDateTime.of(2024, 1, 15, 14, 30);
LocalDateTime dt3 = LocalDateTime.of(2024, 1, 15, 10, 0);

// 比较
dt1.isBefore(dt2);   // true
dt1.isAfter(dt2);    // false
dt1.isEqual(dt3);    // true(同一时刻)

// Duration:时间差
Duration duration = Duration.between(dt1, dt2);
duration.toHours();    // 4
duration.toMinutes(); // 240

// Period:日期差
LocalDate d1 = LocalDate.of(2024, 1, 1);
LocalDate d2 = LocalDate.of(2024, 3, 15);
Period period = Period.between(d1, d2);
period.getMonths();    // 2
period.getDays();     // 14

格式化与解析

java
import java.time.format.*;

// 格式化
LocalDateTime dt = LocalDateTime.of(2024, 3, 15, 14, 30, 45);

DateTimeFormatter fmt = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
String formatted = dt.format(fmt);  // "2024-03-15 14:30:45"

// 解析
LocalDateTime parsed = LocalDateTime.parse("2024-03-15 14:30:45", fmt);

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

实战场景

场景一:日期时间加减

java
LocalDateTime now = LocalDateTime.now();

// 三个月后的第一天
LocalDateTime threeMonthsLater = now.plusMonths(3)
    .withDayOfMonth(1)
    .withHour(0)
    .withMinute(0)
    .withSecond(0);

// 本周周一 00:00
LocalDateTime monday = now.with(DayOfWeek.MONDAY)
    .toLocalDate()
    .atStartOfDay();

场景二:判断是否在工作时间内

java
public boolean isDuringWorkHours(LocalDateTime dt) {
    DayOfWeek day = dt.getDayOfWeek();
    int hour = dt.getHour();
    
    return day != DayOfWeek.SATURDAY 
        && day != DayOfWeek.SUNDAY
        && hour >= 9 && hour < 18;
}

场景三:计算过期时间

java
public boolean isExpired(LocalDateTime createdAt, int days) {
    return createdAt.plusDays(days).isBefore(LocalDateTime.now());
}

与旧 API 的对比

java
// ❌ 旧 API(线程不安全)
Calendar cal = Calendar.getInstance();
cal.add(Calendar.DAY_OF_MONTH, 7);
Date date = cal.getTime();

// ✅ 新 API(线程安全)
LocalDateTime dt = LocalDateTime.now();
LocalDateTime nextWeek = dt.plusDays(7);

小结

LocalDateTime 的常用操作:

操作方法
创建now(), of()
加减plusDays(), minusHours()
获取getYear(), getMonth()
转换toLocalDate(), toInstant()
比较isBefore(), isAfter(), isEqual()
格式化format(), parse()

记住:线程安全是新 API 最大的优势。

基于 VitePress 构建