Java 8 Date/Time API 总览
为什么需要新 API?
Java 旧的日期时间 API(Date、Calendar、SimpleDateFormat)有三大问题:
- 非线程安全:SimpleDateFormat 多线程共享会出问题
- 设计混乱:Date 和 Calendar 职责不清,月份从 0 开始
- 时区处理麻烦:几乎没有正经的时区 API
JDK 8 终于解决了这些问题,带来了全新的 java.time 包。
新 API 家族
java.time
├── LocalDate # 只管日期
├── LocalTime # 只管时间
├── LocalDateTime # 日期 + 时间
├── Instant # 时间戳(UTC)
├── ZonedDateTime # 带时区的日期时间
├── OffsetDateTime # 带固定偏移的日期时间
├── Duration # 时间间隔(秒/纳秒)
├── Period # 日期间隔(年/月/日)
└── DateTimeFormatter # 格式化(线程安全)快速对比
| 旧 API | 新 API | 说明 |
|---|---|---|
| Date | Instant / LocalDateTime | Instant 是时间戳 |
| Calendar | LocalDate / LocalTime / LocalDateTime | 按职责分离 |
| SimpleDateFormat | DateTimeFormatter | 线程安全 |
| TimeZone | ZoneId / ZoneOffset | 更清晰 |
| 无 | Duration / Period | 时间间隔 |
快速入门
创建
java
// 当前时刻
LocalDateTime now = LocalDateTime.now();
// 指定日期时间
LocalDate date = LocalDate.of(2026, 3, 22);
LocalTime time = LocalTime.of(14, 30, 0);
LocalDateTime dt = LocalDateTime.of(date, time);
// 从字符串
LocalDate parsed = LocalDate.parse("2026-03-22");计算
java
LocalDate today = LocalDate.now();
// 加减
today.plusDays(7);
today.minusMonths(1);
// 特殊日期
today.with(TemporalAdjusters.lastDayOfMonth()); // 月末
today.with(TemporalAdjusters.next(DayOfWeek.MONDAY)); // 下周一格式化
java
LocalDateTime dt = LocalDateTime.now();
// 使用预定义格式
String s1 = dt.format(DateTimeFormatter.ISO_LOCAL_DATE_TIME);
// 自定义格式
String s2 = dt.format(DateTimeFormatter.ofPattern("yyyy年MM月dd日 HH:mm"));转换
java
LocalDateTime dt = LocalDateTime.now();
// 转其他类型
dt.toLocalDate(); // → LocalDate
dt.toLocalTime(); // → LocalTime
dt.toInstant(ZoneOffset.UTC); // → Instant
// 从其他类型转来
LocalDateTime.from(instant.atZone(ZoneId.systemDefault()));适用场景
| 场景 | 推荐类型 |
|---|---|
| 用户生日 | LocalDate |
| 会议时间 | ZonedDateTime |
| 执行超时 | Duration |
| 会员有效期 | Period |
| 日志时间戳 | Instant |
| 数据库存储 | Instant(UTC) |
| 显示给用户 | LocalDateTime + 时区 |
总结
新 API 的优势:
- 线程安全:所有类都是不可变的
- 设计清晰:按职责分离(日期、时间、日期时间、时间戳)
- API 友好:月份从 1 开始,年份直接是实际值
- 时区支持:原生支持 ZoneId、ZonedDateTime
- 功能完整:TemporalAdjuster、DateTimeFormatter 等工具完善
结论:新项目直接用 java.time API,旧项目逐步迁移,不要再新建 Date/Calendar/SimpleDateFormat。
