Java LocalDateTime
外观
Java LocalDateTime[编辑 | 编辑源代码]
LocalDateTime 是 Java 日期时间 API(Java 8 引入)中的一个核心类,用于表示不带时区的日期和时间。它结合了 LocalDate 和 LocalTime 的功能,适用于需要处理日期和时间但不涉及时区转换的场景。
概述[编辑 | 编辑源代码]
LocalDateTime 是不可变的(immutable)和线程安全的类,存储的年、月、日、时、分、秒和纳秒信息。它不包含时区或偏移量信息,因此不适合表示全球唯一的时间点(此时应使用 ZonedDateTime 或 Instant)。
主要特点[编辑 | 编辑源代码]
- 格式:`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();
与其它日期时间类的转换[编辑 | 编辑源代码]
转换代码示例:
// 转换为其他类型
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 是处理本地日期时间的理想选择,适用于:
- 生日、纪念日等固定日期时间
- 设备日志时间戳(当设备时区固定时)
- 排班系统、会议安排等业务场景
对于需要时区处理的场景,应考虑使用 ZonedDateTime 或 OffsetDateTime。