JAVA处理时间的 API

在 Java 中,处理时间的 API 主要有两套:

  1. 旧版日期时间 API(java.util.Date / java.util.Calendar)
  2. 新版日期时间 API(java.time 包,JDK8+ 推荐使用)

下面我将分别列出这两类 API 的常用类、是否支持时区、常见方法及推荐用途。

✅ 一、旧版时间 API(java.util

1. java.util.Date

特性 描述
是否包含时区? ❌ 否(本质是 UTC 时间戳)
常用方法 getTime()setTime(long)toString()(输出带本地时区)
缺点 可变、线程不安全、设计混乱

示例:

java 复制代码
Date now = new Date();
System.out.println(now); // 输出格式:Sat Apr 05 14:30:00 CST 2025

2. java.util.Calendar

特性 描述
是否包含时区? ✅ 是(默认系统时区,可设置)
常用方法 getInstance()add()get()getTime()
缺点 线程不安全、API 复杂

示例:

java 复制代码
Calendar cal = Calendar.getInstance();
cal.add(Calendar.DAY_OF_MONTH, 1);
System.out.println(cal.getTime());

3. java.text.SimpleDateFormat

特性 描述
是否支持时区? ✅ 是
常用方法 format(Date)parse(String)
缺点 非线程安全,需加锁或使用 ThreadLocal

示例:

java 复制代码
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
System.out.println(sdf.format(new Date()));

✅ 二、新版时间 API(java.time,推荐使用)

JDK8 引入,位于 java.time 包下,设计更合理、线程安全、支持时区、易读性强。

1. Instant ------ 时间戳(UTC)

特性 描述
是否包含时区? ❌ 否
表示什么? UTC 时间戳(从 1970-01-01T00:00:00Z 开始的秒/纳秒)
常用方法 now()ofEpochMilli(long)plusSeconds()
推荐用途 日志记录、唯一 ID、分布式系统时间同步

示例:

java 复制代码
Instant now = Instant.now(); // 当前 UTC 时间
Instant later = now.plusSeconds(3600); // 1小时后

2. LocalDate / LocalTime / LocalDateTime ------ 不带时区的时间

类名 是否有时区? 表示内容 常用方法
LocalDate ❌ 否 年月日 now()of()plusDays()
LocalTime ❌ 否 时分秒 now()of()plusMinutes()
LocalDateTime ❌ 否 年月日 + 时分秒 now()of()plusHours()

示例:

java 复制代码
LocalDate today = LocalDate.now();
LocalDateTime now = LocalDateTime.now();

3. ZonedDateTime / OffsetDateTime ------ 带时区的时间

类名 是否有时区? 表示内容 常用方法
ZonedDateTime ✅ 是 完整带时区的时间(如 Asia/Shanghai now(ZoneId)withZoneSameInstant()
OffsetDateTime ✅ 是 偏移时间(如 +08:00 now()toZonedDateTime()

示例:

java 复制代码
ZoneId zone = ZoneId.of("Europe/London");
ZonedDateTime londonTime = ZonedDateTime.now(zone);

// 转换为另一个时区
ZonedDateTime shanghaiTime = londonTime.withZoneSameInstant(ZoneId.of("Asia/Shanghai"));

4. ZoneId / ZoneOffset ------ 时区相关

类名 描述 常用方法
ZoneId 代表一个完整的时区(如 Asia/Shanghai of()systemDefault()
ZoneOffset 代表一个偏移量(如 +08:00 ofHours()UTC

示例:

java 复制代码
ZoneId zone = ZoneId.of("America/New_York");
ZoneOffset offset = ZoneOffset.of("+08:00");

5. Duration / Period ------ 时间差

类名 描述 单位 是否支持时区
Duration 时间差(精确到纳秒) 秒、纳秒 ❌ 否(基于 Instant
Period 日期差(精确到天) 天、月、年 ❌ 否

示例:

java 复制代码
Duration duration = Duration.between(Instant.now(), Instant.now().plusSeconds(3600));
Period period = Period.between(LocalDate.now(), LocalDate.now().plusDays(5));

6. DateTimeFormatter ------ 格式化和解析

特性 描述
是否支持时区? ✅ 是(可通过 withZone() 设置)
常用方法 ofPattern(String)format(TemporalAccessor)parse(CharSequence)
推荐用途 格式化输出、解析字符串时间

示例:

java 复制代码
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")
                                              .withZone(ZoneId.of("UTC"));
String formatted = formatter.format(Instant.now());

🧾 总结对比表

API 类名 是否带时区 精度 推荐用途 是否线程安全
Date ❌ 否(实际是 UTC) 毫秒 兼容旧代码
Calendar ✅ 是 毫秒 日期计算
SimpleDateFormat ✅ 是 - 格式化
Instant ❌ 否 纳秒 时间戳
LocalDate / LocalTime / LocalDateTime ❌ 否 天/小时/分钟 本地日期操作
ZonedDateTime ✅ 是 纳秒 带时区时间处理
OffsetDateTime ✅ 是 纳秒 固定偏移时间
Duration ❌ 否 纳秒 时间长度计算
Period ❌ 否 天/月/年 日期长度计算
DateTimeFormatter ✅ 是 - 格式化/解析

✅ 推荐组合用法

场景 推荐 API 组合
记录时间戳(日志、ID生成) Instant
显示给用户看的时间 ZonedDateTime + DateTimeFormatter
日期运算(如"明天"、"下周几") LocalDate
跨时区时间转换 ZonedDateTime + withZoneSameInstant()
时间差计算(精确到毫秒) Duration
日期差计算(按天、月) Period

相关推荐
编程乐学(Arfan开发工程师)4 小时前
56、原生组件注入-原生注解与Spring方式注入
java·前端·后端·spring·tensorflow·bug·lua
Elcker6 小时前
Springboot+idea热更新
spring boot·后端·intellij-idea
南玖yy8 小时前
深入理解 x86 汇编中的符号扩展指令:从 CBW 到 CDQ 的全解析
开发语言·汇编·arm开发·后端·架构·策略模式
江梦寻9 小时前
软件工程教学评价
开发语言·后端·macos·架构·github·软件工程
美好的事情能不能发生在我身上9 小时前
苍穹外卖Day11代码解析以及深入思考
java·spring boot·后端·spring·架构
不良手残10 小时前
Redisson + Lettuce 在 Spring Boot 中的最佳实践方案
java·spring boot·redis·后端
一线大码11 小时前
SpringBoot 和 MySQL 的事务隔离级别关系
spring boot·后端·mysql
罗政11 小时前
基于 SpringBoot + Vue 在线点餐系统(前后端分离)
vue.js·spring boot·后端
曼岛_11 小时前
[架构之美]深入优化Spring Boot WebFlux应用
spring boot·后端·架构