跳转到内容

Java LocalDateTime

来自代码酷

Java LocalDateTime[编辑 | 编辑源代码]

LocalDateTime 是 Java 日期时间 API(Java 8 引入)中的一个核心类,用于表示不带时区的日期和时间。它结合了 LocalDateLocalTime 的功能,适用于需要处理日期和时间但不涉及时区转换的场景。

概述[编辑 | 编辑源代码]

LocalDateTime 是不可变的(immutable)和线程安全的类,存储的年、月、日、时、分、秒和纳秒信息。它不包含时区或偏移量信息,因此不适合表示全球唯一的时间点(此时应使用 ZonedDateTimeInstant)。

主要特点[编辑 | 编辑源代码]

  • 格式:`yyyy-MM-ddTHH:mm:ss.SSS`(默认 ISO-8601)
  • 精度:最高支持纳秒(nanosecond)
  • 时区:无时区信息
  • 不可变性:所有修改操作返回新对象

创建 LocalDateTime[编辑 | 编辑源代码]

静态工厂方法[编辑 | 编辑源代码]

以下是创建 LocalDateTime 的常见方式:

// 获取当前日期时间
LocalDateTime now = LocalDateTime.now();

// 指定具体日期时间
LocalDateTime specificDateTime = LocalDateTime.of(2023, 5, 15, 14, 30, 45);

// 解析字符串
LocalDateTime parsedDateTime = LocalDateTime.parse("2023-05-15T14:30:45");

// 组合 LocalDate 和 LocalTime
LocalDate date = LocalDate.of(2023, 5, 15);
LocalTime time = LocalTime.of(14, 30, 45);
LocalDateTime combined = LocalDateTime.of(date, time);

输出示例[编辑 | 编辑源代码]

对于 `LocalDateTime.now()` 可能输出:

2023-11-20T15:42:18.123456789

常用操作[编辑 | 编辑源代码]

获取字段值[编辑 | 编辑源代码]

LocalDateTime dt = LocalDateTime.parse("2023-05-15T14:30:45");

int year = dt.getYear();          // 2023
Month month = dt.getMonth();      // MAY
int day = dt.getDayOfMonth();     // 15
int hour = dt.getHour();          // 14
int minute = dt.getMinute();      // 30
int second = dt.getSecond();      // 45

日期时间计算[编辑 | 编辑源代码]

LocalDateTime dt = LocalDateTime.parse("2023-05-15T14:30:45");

// 加减操作
LocalDateTime nextHour = dt.plusHours(1);
LocalDateTime prevWeek = dt.minusWeeks(1);

// 使用 Period 和 Duration
LocalDateTime nextMonth = dt.plus(Period.ofMonths(1));
LocalDateTime in30Minutes = dt.plus(Duration.ofMinutes(30));

时间比较[编辑 | 编辑源代码]

LocalDateTime dt1 = LocalDateTime.parse("2023-05-15T14:30:45");
LocalDateTime dt2 = LocalDateTime.parse("2023-05-16T08:15:30");

boolean isBefore = dt1.isBefore(dt2);  // true
boolean isAfter = dt1.isAfter(dt2);    // false
boolean isEqual = dt1.isEqual(dt2);    // false

格式化与解析[编辑 | 编辑源代码]

使用 DateTimeFormatter 进行格式转换:

LocalDateTime dt = LocalDateTime.now();

// 自定义格式化
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss");
String formatted = dt.format(formatter);  // "2023/11/20 15:42:18"

// 解析
LocalDateTime parsed = LocalDateTime.parse("2023/05/15 14:30", formatter);

实际应用案例[编辑 | 编辑源代码]

案例1:会议时间计算[编辑 | 编辑源代码]

计算会议结束时间(已知开始时间和持续时间):

LocalDateTime meetingStart = LocalDateTime.of(2023, 5, 15, 14, 0);
Duration meetingDuration = Duration.ofHours(2).plusMinutes(15);

LocalDateTime meetingEnd = meetingStart.plus(meetingDuration);
// 结果:2023-05-15T16:15

案例2:生日提醒[编辑 | 编辑源代码]

检查今天是否是用户的生日:

LocalDate today = LocalDate.now();
LocalDateTime birthday = LocalDateTime.of(1990, 5, 15, 0, 0);

boolean isBirthday = birthday.getMonth() == today.getMonth() 
                  && birthday.getDayOfMonth() == today.getDayOfMonth();

与其它日期时间类的转换[编辑 | 编辑源代码]

graph LR A[LocalDateTime] -->|toLocalDate| B[LocalDate] A -->|toLocalTime| C[LocalTime] A -->|atZone| D[ZonedDateTime] A -->|toInstant| E[Instant] B & C -->|atTime/atDate| A D -->|toLocalDateTime| A

转换代码示例:

// 转换为其他类型
LocalDate date = dt.toLocalDate();
LocalTime time = dt.toLocalTime();
ZonedDateTime zoned = dt.atZone(ZoneId.of("Asia/Shanghai"));
Instant instant = zoned.toInstant();

// 从其他类型转换
LocalDateTime fromDateAndTime = LocalDateTime.of(date, time);
LocalDateTime fromZoned = zoned.toLocalDateTime();

性能注意事项[编辑 | 编辑源代码]

  • LocalDateTime 对象占用约 16-24 字节内存(取决于 JVM 实现)
  • 创建操作比修改操作更高效(因为不可变性)
  • 频繁解析字符串时,考虑重用 DateTimeFormatter 实例

最佳实践[编辑 | 编辑源代码]

1. 在不需要时区的场景优先使用 LocalDateTime 2. 避免使用 `null`,可以用 `Optional<LocalDateTime>` 3. 数据库存储时对应 TIMESTAMP 类型(不带时区) 4. 与前端交互时明确约定格式(通常 ISO-8601)

常见问题[编辑 | 编辑源代码]

为什么我的 LocalDateTime 输出包含 "T"?[编辑 | 编辑源代码]

这是 ISO-8601 标准格式,日期和时间之间用 "T" 分隔。如需自定义格式,请使用 DateTimeFormatter

如何获取两个日期之间的天数差?[编辑 | 编辑源代码]

LocalDateTime dt1 = ...;
LocalDateTime dt2 = ...;

long daysBetween = ChronoUnit.DAYS.between(dt1, dt2);

总结[编辑 | 编辑源代码]

LocalDateTime 是处理本地日期时间的理想选择,适用于:

  • 生日、纪念日等固定日期时间
  • 设备日志时间戳(当设备时区固定时)
  • 排班系统、会议安排等业务场景

对于需要时区处理的场景,应考虑使用 ZonedDateTimeOffsetDateTime