在Java编程中,System类的nanoTime方法和currentTimeMillis方法是获取时间信息的常用工具,两者在精度、适用场景上存在明显差异,开发者需要根据实际需求选择合适的方法,避免时间计算出现偏差。

精度定义与数值范围
currentTimeMillis返回的是当前时间与UTC 1970年1月1日0点0分0秒之间的时间差,单位是毫秒,其精度受操作系统时钟精度影响,通常精度在10-15毫秒左右,返回值为long类型,最大值约为292亿年后的时间,足以覆盖绝大多数业务场景。
nanoTime返回的是当前JVM的高精度时间源纳秒数,单位是纳秒,理论精度可以达到纳秒级,但实际精度依赖底层硬件和操作系统的支持,通常精度在微秒级左右。返回值同样是long类型,但其数值没有固定的时间原点,仅能用于计算时间差,不能直接转换为日期时间。
底层实现差异
currentTimeMillis的底层实现依赖操作系统的系统时间,Windows系统下通过GetSystemTimeAsFileTime获取,Linux系统下通过gettimeofday或者clock_gettime获取,返回的时间会受系统时间调整的影响,比如手动修改系统时间、NTP时间同步都会导致该方法返回的值发生变化。
nanoTime的底层实现依赖JVM的高精度计时器,Windows系统下通常使用QueryPerformanceCounter,Linux系统下使用clock_gettime(CLOCK_MONOTONIC),使用的是单调时间源,不会受系统时间调整的影响,只要JVM不重启,相同时间间隔内的两次调用差值就是实际流逝的时间。
适用场景对比
| 对比维度 | System.currentTimeMillis | System.nanoTime |
|---|---|---|
| 适用场景 | 获取当前日期时间、记录日志时间戳、计算跨系统的时间差 | 计算代码段执行耗时、性能基准测试、短时间内的时间间隔统计 |
| 时间原点 | UTC 1970年1月1日0点0分0秒 | 无固定原点,JVM启动时确定 |
| 受系统时间调整影响 | 是 | 否 |
| 典型精度 | 毫秒级 | 微秒到纳秒级 |
代码示例
currentTimeMillis使用示例
以下代码用于获取当前时间戳并转换为可读的日期格式:
import java.text.SimpleDateFormat;
import java.util.Date;
public class CurrentTimeMillisDemo {
public static void main(String[] args) {
// 获取当前时间的毫秒时间戳
long timestamp = System.currentTimeMillis();
System.out.println("当前毫秒时间戳:" + timestamp);
// 转换为可读日期
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String dateStr = sdf.format(new Date(timestamp));
System.out.println("对应日期时间:" + dateStr);
}
}
nanoTime使用示例
以下代码用于统计一段代码的执行耗时,精度更高:
public class NanoTimeDemo {
public static void main(String[] args) {
// 记录开始时间
long start = System.nanoTime();
// 模拟一段执行逻辑
int sum = 0;
for (int i = 0; i < 1000000; i++) {
sum += i;
}
// 记录结束时间
long end = System.nanoTime();
// 计算耗时,转换为微秒
long costNano = end - start;
double costMicro = costNano / 1000.0;
System.out.println("代码执行耗时:" + costNano + "纳秒,约" + costMicro + "微秒");
}
}
注意事项
- 不要将nanoTime的返回值用于获取当前日期时间,因为其没有固定的时间原点,不同JVM实例的返回值没有可比性。
- 在计算短时间内的耗时场景优先使用nanoTime,避免currentTimeMillis的毫秒级精度导致统计结果不准确。
- 如果需要在分布式系统中计算时间差,不要使用nanoTime,因为不同机器的JVM计时器起点不同,差值没有意义,此时应该使用currentTimeMillis。
- nanoTime的返回值是long类型,计算差值时需要注意溢出问题,不过由于纳秒到long溢出的时间非常长,正常业务场景下几乎不会出现该问题。
System.nanoTimecurrentTimeMillis时间精度Java时间API修改时间:2026-06-21 15:24:24