Java 8之前的Date、Calendar线程不安全、设计混乱。Java 8引入的java.time包彻底解决了这些问题。本文系统讲解新日期时间API。
一、核心类
| 类 | 用途 |
|---|---|
| LocalDate | 日期 |
| LocalTime | 时间 |
| LocalDateTime | 日期+时间 |
| ZonedDateTime | 带时区 |
| Instant | 时间戳 |
| Duration | 时间间隔 |
| Period | 日期间隔 |
| DateTimeFormatter | 格式化 |
二、创建与操作
java
复制
下载
LocalDate date = LocalDate.now(); LocalDate date2 = LocalDate.of(2024, 1, 1); LocalDate parsed = LocalDate.parse("2024-01-01"); LocalTime time = LocalTime.now(); LocalTime time2 = LocalTime.of(10, 30, 0); LocalDateTime dt = LocalDateTime.now(); LocalDateTime dt2 = LocalDateTime.of(2024, 1, 1, 10, 30); // 操作 LocalDate tomorrow = date.plusDays(1); LocalDate lastMonth = date.minusMonths(1); LocalDate withYear = date.withYear(2025); // 获取字段 date.getYear(); date.getMonth(); // Month枚举 date.getMonthValue(); // 1-12 date.getDayOfWeek(); // DayOfWeek枚举 date.getDayOfMonth(); date.lengthOfMonth(); date.isLeapYear();三、时间戳与Instant
java
复制
下载
Instant now = Instant.now(); long epochMilli = now.toEpochMilli(); Instant fromMilli = Instant.ofEpochMilli(1704067200000L); LocalDateTime dt = LocalDateTime.ofInstant(fromMilli, ZoneId.systemDefault());
四、时区
java
复制
下载
ZoneId zone = ZoneId.of("Asia/Shanghai"); ZonedDateTime zdt = ZonedDateTime.now(zone); // 时区转换 ZonedDateTime ny = zdt.withZoneSameInstant(ZoneId.of("America/New_York")); System.out.println(ny); // 所有可用时区 ZoneId.getAvailableZoneIds().forEach(System.out::println);五、格式化
java
复制
下载
DateTimeFormatter fmt = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); String s = LocalDateTime.now().format(fmt); LocalDateTime dt = LocalDateTime.parse("2024-01-01 10:30:00", fmt); // 预定义格式 DateTimeFormatter.ISO_LOCAL_DATE DateTimeFormatter.ISO_DATE_TIME // 本地化 DateTimeFormatter.ofLocalizedDate(FormatStyle.FULL) .withLocale(Locale.CHINA);六、Duration与Period
java
复制
下载
// Duration:时间间隔 Duration d = Duration.between( LocalTime.of(10, 0), LocalTime.of(12, 30)); System.out.println(d.toMinutes()); // 150 // Period:日期间隔 Period p = Period.between( LocalDate.of(2024, 1, 1), LocalDate.of(2024, 3, 15)); System.out.println(p.getMonths() + "个月" + p.getDays() + "天"); // ChronoUnit long days = ChronoUnit.DAYS.between(start, end); long hours = ChronoUnit.HOURS.between(t1, t2);
七、与旧API转换
java
复制
下载
// Date -> Instant Date date = new Date(); Instant instant = date.toInstant(); // Instant -> Date Date fromInstant = Date.from(instant); // Calendar -> ZonedDateTime Calendar cal = Calendar.getInstance(); ZonedDateTime zdt = ZonedDateTime.ofInstant( cal.toInstant(), cal.getZone()); // LocalDateTime <-> Date Date d = Date.from(dt.atZone(ZoneId.systemDefault()).toInstant()); LocalDateTime ldt = LocalDateTime.ofInstant(d.toInstant(), ZoneId.systemDefault());
八、实战:日期工具类
java
复制
下载
public class DateUtils { public static final DateTimeFormatter DATE_FMT = DateTimeFormatter.ofPattern("yyyy-MM-dd"); public static final DateTimeFormatter DATETIME_FMT = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); public static String format(LocalDateTime dt) { return dt == null ? "" : dt.format(DATETIME_FMT); } public static LocalDateTime parse(String s) { return LocalDateTime.parse(s, DATETIME_FMT); } public static long daysBetween(LocalDate a, LocalDate b) { return ChronoUnit.DAYS.between(a, b); } public static boolean isSameDay(LocalDateTime a, LocalDateTime b) { return a.toLocalDate().equals(b.toLocalDate()); } public static LocalDateTime startOfDay(LocalDate date) { return date.atStartOfDay(); } public static LocalDateTime endOfDay(LocalDate date) { return date.atTime(LocalTime.MAX); } public static boolean isWeekend(LocalDate date) { DayOfWeek dow = date.getDayOfWeek(); return dow == DayOfWeek.SATURDAY || dow == DayOfWeek.SUNDAY; } }九、注意事项
线程安全:java.time全部不可变,线程安全。
不要用==比较:用equals或isEqual。
时区问题:数据库存UTC,展示转本地。
MySQL映射:
DATETIME对应LocalDateTime,TIMESTAMP对应Instant。Jackson序列化:配置
JavaTimeModule。
java
复制
下载
@Bean public ObjectMapper objectMapper() { ObjectMapper mapper = new ObjectMapper(); mapper.registerModule(new JavaTimeModule()); mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS); return mapper; }十、总结
java.time设计优雅、线程安全。掌握LocalDateTime、ZonedDateTime、Duration、DateTimeFormatter,能应对几乎所有日期时间场景。