java.time 包详解
Java 8 引入的 java.time
包是全新的日期和时间 API,用于替代旧的 java.util.Date
和 java.util.Calendar
类。这个包基于 Joda-Time 库设计,提供了更直观、更易用且线程安全的日期时间处理功能。
核心类
1. 基本日期时间类
-
LocalDate:只包含日期,不包含时间和时区信息
-
LocalTime:只包含时间,不包含日期和时区信息
-
LocalDateTime:包含日期和时间,但不包含时区信息
LocalDate today = LocalDate.now(); LocalDate specificDate = LocalDate.of(2023, Month.JUNE, 15);LocalTime currentTime = LocalTime.now(); LocalTime specificTime = LocalTime.of(14, 30, 45);LocalDateTime currentDateTime = LocalDateTime.now();
LocalDateTime specificDateTime = LocalDateTime.of(2023, Month.JUNE, 15, 14, 30);
2. 时区相关类
-
ZonedDateTime:包含日期、时间和时区信息
-
ZoneId:表示时区标识符
ZonedDateTime zonedDateTime = ZonedDateTime.now(); ZonedDateTime tokyoTime = ZonedDateTime.now(ZoneId.of("Asia/Tokyo"));ZoneId londonZone = ZoneId.of("Europe/London");
3. 时间点和持续时间类
-
Instant:时间线上的瞬时点(Unix 时间戳)
-
Duration:基于时间的持续时间(秒、纳秒)
-
Period:基于日期的持续时间(年、月、日)
Instant now = Instant.now();Duration duration = Duration.between(startTime, endTime);Period period = Period.between(startDate, endDate);
常用操作
日期时间计算
LocalDate tomorrow = LocalDate.now().plusDays(1);
LocalTime anHourLater = LocalTime.now().plusHours(1);
LocalDateTime nextWeek = LocalDateTime.now().plusWeeks(1);
日期时间比较
boolean isBefore = LocalDate.parse("2023-06-01").isBefore(LocalDate.parse("2023-06-15"));
boolean isAfter = LocalTime.of(14, 0).isAfter(LocalTime.of(12, 0));
格式化与解析
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
String formatted = LocalDateTime.now().format(formatter);
LocalDateTime parsed = LocalDateTime.parse("2023-06-15 14:30:00", formatter);
实用功能
时间单位枚举
ChronoUnit
枚举提供了常见的时间单位:
long daysBetween = ChronoUnit.DAYS.between(startDate, endDate);
时间调整器
TemporalAdjusters
类提供了常用的日期调整方法:
LocalDate firstDayOfMonth = LocalDate.now().with(TemporalAdjusters.firstDayOfMonth());
LocalDate nextFriday = LocalDate.now().with(TemporalAdjusters.next(DayOfWeek.FRIDAY));
自定义调整器
LocalDate nextWorkingDay = LocalDate.now().with(temporal -> {DayOfWeek day = DayOfWeek.from(temporal);int daysToAdd = 1;if (day == DayOfWeek.FRIDAY) daysToAdd = 3;if (day == DayOfWeek.SATURDAY) daysToAdd = 2;return temporal.plus(daysToAdd, ChronoUnit.DAYS);
});
与传统日期类的转换
转换为传统类
Date legacyDate = Date.from(Instant.now());
Calendar legacyCalendar = GregorianCalendar.from(ZonedDateTime.now());
从传统类转换
Instant instant = legacyDate.toInstant();
ZonedDateTime zdt = legacyCalendar.toZonedDateTime();
总结
java.time
包的主要优势:
-
清晰的设计:将日期、时间、时区等概念明确分离
-
不可变性:所有类都是不可变的,线程安全
-
流畅的API:方法链式调用,代码更易读
-
全面的功能:支持各种日期时间计算和操作
-
更好的时区处理:明确区分了本地时间和带时区的时间
这个包已经成为 Java 中处理日期时间的标准方式,推荐在新项目中使用它而不是旧的日期时间类。