准备工作:获取一个 Unix 时间戳
为了演示,我们先获取一个当前时间的 Unix 时间戳,在 Java 中,可以通过 System.currentTimeMillis() 获取,但它返回的是毫秒数,所以需要除以 1000 得到秒数。

long currentUnixTimestampInSeconds = System.currentTimeMillis() / 1000;
System.out.println("当前的 Unix 时间戳 (秒): " + currentUnixTimestampInSeconds);
// 如果你的时间戳是毫秒级的,直接使用即可
long currentUnixTimestampInMilliseconds = System.currentTimeMillis();
System.out.println("当前的 Unix 时间戳 (毫秒): " + currentUnixTimestampInMilliseconds);
使用 Java 8+ 的 java.time 包 (推荐)
这是目前最现代、最推荐的方法。java.time API 在 Java 8 中引入,它设计良好,线程安全,并且功能强大。
时间戳是秒(Instant)
如果时间戳是秒级的,应该使用 Instant.ofEpochSecond()。
import java.time.Instant;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
public class Java8TimeConversion {
public static void main(String[] args) {
long unixTimestampInSeconds = 1672531200L; // 示例:2025-01-01 00:00:00 UTC
// 1. 将秒级时间戳转换为 Instant
Instant instant = Instant.ofEpochSecond(unixTimestampInSeconds);
// 2. 转换为特定时区的 ZonedDateTime
// ZoneId.systemDefault() 使用系统的默认时区
ZonedDateTime zonedDateTime = instant.atZone(ZoneId.systemDefault());
System.out.println("默认时区: " + zonedDateTime);
// 指定时区,"Asia/Shanghai"
ZonedDateTime shanghaiTime = instant.atZone(ZoneId.of("Asia/Shanghai"));
System.out.println("上海时间: " + shanghaiTime);
// 3. 格式化为特定格式的字符串
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss z");
String formattedDateTime = shanghaiTime.format(formatter);
System.out.println("格式化后的上海时间: " + formattedDateTime);
}
}
时间戳是毫秒(Instant)
如果时间戳是毫秒级(System.currentTimeMillis() 的结果),应该使用 Instant.ofEpochMilli()。
import java.time.Instant;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
public class Java8TimeConversionMillis {
public static void main(String[] args) {
long unixTimestampInMilliseconds = 1672531200000L; // 示例:2025-01-01 00:00:00 UTC
// 1. 将毫秒级时间戳转换为 Instant
Instant instant = Instant.ofEpochMilli(unixTimestampInMilliseconds);
// 2. 转换为特定时区并格式化
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")
.withZone(ZoneId.of("America/New_York")); // 直接指定时区
String formattedDateTime = formatter.format(instant);
System.out.println("纽约时间: " + formattedDateTime);
}
}
使用旧版 Java 的 java.util.Date 和 SimpleDateFormat
在 Java 8 之前,通常使用 java.util.Date 和 SimpleDateFormat。注意:Date 类本身是时区敏感的,但其很多方法已废弃,SimpleDateFormat 不是线程安全的。

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.TimeZone;
public class LegacyDateConversion {
public static void main(String[] args) {
long unixTimestampInSeconds = 1672531200L; // 示例:2025-01-01 00:00:00 UTC
// 1. 将秒级时间戳乘以 1000 转换为毫秒,再创建 Date 对象
// Date 的构造函数接受的是毫秒数
Date date = new Date(unixTimestampInSeconds * 1000L);
// 2. 创建 SimpleDateFormat 并设置时区
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss z");
sdf.setTimeZone(TimeZone.getTimeZone("Asia/Shanghai")); // 设置时区为上海
// 3. 格式化日期
String formattedDateTime = sdf.format(date);
System.out.println("使用旧版 API 的上海时间: " + formattedDateTime);
}
}
使用 Joda-Time 库
在 Java 8 之前,Joda-Time 是事实上的标准日期时间库,它比 java.util.Date 好用得多,如果你在使用旧版 Java 且不能升级到 Java 8,Joda-Time 是一个很好的选择。
你需要添加 Joda-Time 的依赖(Maven):
<dependency>
<groupId>joda-time</groupId>
<artifactId>joda-time</artifactId>
<version>2.12.5</version> <!-- 使用最新版本 -->
</dependency>
import org.joda.time.DateTime;
import org.joda.time.DateTimeZone;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;
public class JodaTimeConversion {
public static void main(String[] args) {
long unixTimestampInSeconds = 1672531200L; // 示例:2025-01-01 00:00:00 UTC
// 1. 将秒级时间戳乘以 1000 转换为毫秒,再创建 DateTime 对象
// Joda-Time 的构造函数也接受毫秒数
DateTime dateTime = new DateTime(unixTimestampInSeconds * 1000L, DateTimeZone.UTC);
// 2. 转换为特定时区
DateTime shanghaiTime = dateTime.withZone(DateTimeZone.forID("Asia/Shanghai"));
// 3. 格式化日期
DateTimeFormatter formatter = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss z");
String formattedDateTime = shanghaiTime.toString(formatter);
System.out.println("使用 Joda-Time 的上海时间: " + formattedDateTime);
}
}
总结与对比
| 方法 | 优点 | 缺点 | 推荐场景 |
|---|---|---|---|
java.time (Java 8+) |
现代、API 设计优秀、线程安全、功能强大 | 需要 Java 8 或更高版本 | 所有 Java 8+ 项目的首选 |
java.util.Date (旧版) |
兼容所有 Java 版本 | API 设计陈旧、多线程不安全、大部分方法已废弃 | 维护旧版 Java 项目(不推荐新代码使用) |
| Joda-Time | API 比 Date 好用,功能强大 |
在 Java 8+ 中已被 java.time 取代,引入了第三方依赖 |
必须使用旧版 Java 且无法引入 java.time 的项目 |
核心要点
- 区分秒和毫秒:这是最常见的错误。
System.currentTimeMillis()是毫秒,很多系统 API(如数据库)可能返回秒,确保使用正确的ofEpochSecond()或ofEpochMilli()。 - 处理时区:Unix 时间戳本身是 UTC 时间,在转换为本地时间时,必须明确指定
ZoneId或TimeZone,否则结果可能不符合预期。 - 首选
java.time:如果你的项目使用的是 Java 8 或更高版本,请务必使用java.timeAPI,它是未来,也是目前最规范、最安全的做法。

