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

相关推荐
沃夫上校3 小时前
Feign调Post接口异常:Incomplete output stream
java·后端·微服务
LeeGe3 小时前
SpringAOP中@within和@annotation以及 @within和@target的区别
后端
一个平平无奇的Java小学生3 小时前
Spring Cloud Alibaba 微服务从入门到生产部署完整指南
后端
一个平平无奇的Java小学生3 小时前
Spring Cloud Alibaba 微服务实战指南
后端
张小洛3 小时前
Spring IOC容器核心阶段解密:★Bean实例化全流程深度剖析★
java·后端·spring·ioc容器·bean实例化
小王子10243 小时前
Django+DRF 实战:从异常捕获到自定义错误信息
后端·django·web开发
hdsoft_huge3 小时前
Spring Boot 高并发框架实现方案:数字城市的奇妙之旅
java·spring boot·后端
00后程序员4 小时前
WebView 无法调用原生分享功能?调试复现与异常排查全过程
后端
struggleupwards4 小时前
go-cache 单机缓存
后端
struggleupwards4 小时前
golang 实现删除切片特定下标元素的方法
后端