在 Java 中,处理时间的 API 主要有两套:
旧版日期时间 API(java.util.Date / java.util.Calendar)
新版日期时间 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
示例:
java
复制代码
Calendar cal = Calendar.getInstance();
cal.add(Calendar.DAY_OF_MONTH, 1);
System.out.println(cal.getTime());
3. java.text.SimpleDateFormat
示例:
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));
示例:
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