技术科普

Java 时区 API:java.time 的正确用法

Java 8 之前,java.util.Date 和 Calendar 的时区处理常令人困惑。Java 8 引入的 java.time 包提供了更清晰的模型。

核心类型

  • Instant:时间轴上的瞬间,以 UTC 表示
  • LocalDateTime:不含时区的本地日期时间
  • ZonedDateTime:带时区和夏令时规则的日期时间
  • OffsetDateTime:带固定偏移量的日期时间
  • ZoneId:时区标识,如 Asia/Shanghai

常用操作

获取当前瞬间:Instant.now()。转换为某时区:instant.atZone(ZoneId.of("Asia/Shanghai"))。格式化:DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm")。

常见误区

  • 用 LocalDateTime 表示跨时区事件,丢失偏移信息
  • 手动加减小时,忽略夏令时
  • 使用旧版 TimeZone.getTimeZone 而不校验时区 ID
  • 在数据库中存储本地时间而非 UTC

建议

服务端内部使用 Instant 或 UTC,展示层再转换为用户时区。时区 ID 使用 IANA 名称,避免使用缩写(如 CST 有歧义)。定期更新 JDK 以获取最新时区数据。

java.time 的设计原则是“显式表达时区”,让类型系统帮助开发者避免错误。