在 Java 中获取系统时间的毫秒数,主要有以下几种常用方法,适用于不同的场景。

System.currentTimeMillis() (最常用)
这是获取当前时间毫秒数最常用、最高效的方法,它返回自 1970 年 1 月 1 日 00:00:00 UTC(Unix 纪元)以来经过的毫秒数。
特点:
- 简单高效:直接调用 JVM 的底层方法,性能开销极小。
- 用途广泛:通常用于计算时间间隔、记录日志时间戳、作为程序运行的唯一标识符等。
- 不是日历时间:它只是一个
long类型的数字,不代表具体的年、月、日、时、分、秒,如果需要格式化的时间,需要结合java.time或java.util.Date等类进行转换。
示例代码:
public class GetCurrentTimeMillis {
public static void main(String[] args) {
// 获取当前时间的毫秒数
long currentTimeMillis = System.currentTimeMillis();
System.out.println("自 1970-01-01 00:00:00 UTC 以来的毫秒数: " + currentTimeMillis);
// 一个常见的用途:计算代码执行时间
long startTime = System.currentTimeMillis();
// 模拟一段耗时操作
try {
Thread.sleep(1000); // 暂停 1 秒
} catch (InterruptedException e) {
e.printStackTrace();
}
long endTime = System.currentTimeMillis();
long duration = endTime - startTime;
System.out.println("代码执行耗时: " + duration + " 毫秒");
}
}
输出示例:

自 1970-01-01 00:00:00 UTC 以来的毫秒数: 1678886401234
代码执行耗时: 1000 毫秒
System.nanoTime() (用于高精度计时)
这个方法返回一个高精度的、相对于某个任意固定但未知的时间点的纳秒数,它不用于表示真实世界的时间,而专门用于测量代码的执行时间。
特点:
- 高精度:以纳秒为单位,比
currentTimeMillis()精度高得多。 - 不可用于时间戳:它的起点是任意的,在不同 JVM 运行甚至同一 JVM 重启后都可能改变,不能用它来表示“几点几分”。
- 用于性能测试:非常适合测量代码块、算法的执行耗时。
示例代码:
public class GetNanoTime {
public static void main(String[] args) {
// 获取高精度纳秒时间
long startTimeNano = System.nanoTime();
// 模拟一段耗时操作
try {
Thread.sleep(500); // 暂停 500 毫秒
} catch (InterruptedException e) {
e.printStackTrace();
}
long endTimeNano = System.nanoTime();
// 计算耗时,通常转换为毫秒或微秒以便阅读
long durationNano = endTimeNano - startTimeNano;
double durationMillis = durationNano / 1_000_000.0; // 转换为毫秒
System.out.println("代码执行耗时 (纳秒): " + durationNano);
System.out.println("代码执行耗时 (毫秒): " + durationMillis);
}
}
输出示例:
代码执行耗时 (纳秒): 500345678
代码执行耗时 (毫秒): 500.345678
注意:
System.nanoTime()即使在系统时间被用户修改的情况下,也能保证其单调递增,非常适合精确的性能测量。
使用 java.time.Instant (Java 8+ 推荐)
如果你需要一个同时包含日期和时间(精确到纳秒)的对象,并且可以轻松地获取其毫秒数,java.time.Instant 是现代 Java 的首选。
Instant 类代表时间线上的一个瞬时点,类似于 System.currentTimeMillis(),但它提供了更丰富的 API。
特点:
- 现代化 API:Java 8 引入的
java.time包是处理日期和时间的标准,功能强大且易用。 - 可读性强:可以方便地格式化为字符串,或者获取年、月、日等字段。
- 获取毫秒数:可以直接调用
toEpochMilli()方法获取毫秒数。
示例代码:
import java.time.Instant;
public class GetTimeWithInstant {
public static void main(String[] args) {
// 获取当前时间的 Instant 对象
Instant now = Instant.now();
// 获取毫秒数 (与 System.currentTimeMillis() 结果基本一致)
long millis = now.toEpochMilli();
System.out.println("当前时间的 Instant 对象: " + now);
System.out.println("自 1970-01-01 00:00:00 UTC 以来的毫秒数: " + millis);
// Instant 的优势:可以轻松进行格式化
System.out.println("格式化后的时间 (ISO-8601): " + now.toString());
}
}
输出示例:
当前时间的 Instant 对象: 2025-03-17T10:30:45.123Z
自 1970-01-01 00:00:00 UTC 以来的毫秒数: 1679044245123
格式化后的时间 (ISO-8601): 2025-03-17T10:30:45.123Z
总结与选择
| 方法 | 返回值 | 主要用途 | 精度 | 备注 |
|---|---|---|---|---|
System.currentTimeMillis() |
long (毫秒) |
获取时间戳、计算时间间隔、唯一ID | 毫秒级 | 最常用,性能最高,不适合处理日历逻辑。 |
System.nanoTime() |
long (纳秒) |
高精度性能测量、代码耗时分析 | 纳秒级 | 不能用于表示真实时间,起点不确定。 |
Instant.now().toEpochMilli() |
long (毫秒) |
获取时间戳,同时希望使用现代日期时间API | 毫秒级 | Java 8+ 推荐,功能更全面,可读性好。 |
如何选择?
- 如果你只需要一个时间戳或计算简单的耗时:使用
System.currentTimeMillis(),这是最简单、最快的选择。 - 如果你需要精确测量代码块的执行时间(例如性能测试):使用
System.nanoTime()。 - 如果你正在使用 Java 8 或更高版本,并且希望处理日期、时间、时区等复杂逻辑:使用
java.time.Instant或其他java.time包中的类(如LocalDateTime,ZonedDateTime等),它们是未来趋势,也更安全、更强大。
