56

什么是使用 Java 访问系统时钟的简单/简便方法,以便我可以计算事件的经过时间?

4

6 回答 6

84

我会避免System.currentTimeMillis()用于测量经过的时间。currentTimeMillis()返回“挂钟”时间,该时间可能会发生变化(例如:夏令时,管理员用户更改时钟)并扭曲您的间隔测量。

System.nanoTime()另一方面,返回自“某个参考点”(例如,JVM 启动)以来的纳秒数,因此不会受到系统时钟变化的影响。

于 2008-10-27T11:54:44.703 回答
27

这是一些示例代码。

long startTime = System.currentTimeMillis();
// Run some code;
long stopTime = System.currentTimeMillis();

System.out.println("Elapsed time was " + (stopTime - startTime) + " miliseconds.");
于 2008-10-27T02:28:21.943 回答
9

Apache Commons-Lang 也有适合您目的的 StopWatch 类。它使用 System.currentTimeMillis(),所以你仍然会遇到分辨率问题,但你可以暂停并做单圈时间等。我现在将它用作事件统计的标准。

http://commons.apache.org/lang/api-release/org/apache/commons/lang/time/StopWatch.html

于 2008-10-27T03:58:13.637 回答
8

Leigh的答案是正确的。

java.time

Java 8 及更高版本内置了 java.time 框架。

AnInstant是 UTC 时间线上的时刻,具有纳秒级分辨率(最多 9 位小数秒的小数部分)。该now方法获取当前的日期时间时刻。

Instant now = Instant.now();

2016-03-12T04:29:39.123Z

您可以将一对Instant对象之间的经过时间计算为Duration. 持续时间使用纳秒分辨率,最大值为可以长时间保持的秒数。这大于目前估计的宇宙年龄。

Duration duration = Duration.between( startInstant , stopInstant );

的默认输出为Duration::toString标准ISO 8601格式。您还可以询问纳秒 ( toNanos) 或毫秒 ( toMillis) 的总计数,以及其他数量。

爪哇 8

在 Java 8 中,获取当前时刻仅解析为毫秒分辨率(最多 3 位小数秒的小数部分)。因此,虽然 java.time 类可以存储纳秒,但它们只能以毫秒确定当前时刻。此限制是由于遗留问题(默认Clock实现使用System.currentTimeMillis())。

爪哇 9

在 Java 9 及更高版本中,默认Clock实现可以以纳秒的分辨率确定当前时刻。实际上这样做取决于计算机时钟硬件的精细度。

有关更多信息,请参阅此 OpenJDK 问题页面:增加 java.time.Clock.systemUTC() 的实现精度

微基准

如果您的目的是进行基准测试,请务必查看其他问题,例如:

框架可用于协助进行短期基准测试。

于 2016-03-16T23:39:18.250 回答
5

java.lang.System.currentTimeMillis()或者java.lang.System.nanoTime()应该可以测量经过的时间。

于 2008-10-27T02:07:56.120 回答
3

这是我使用 System.nanoTime() 编写的一个小型 StopWatch 类,如 Leigh 的回答中所建议的那样:

public class StopWatch {
    // Constructor
    public StopWatch() {
    }

    // Public API
    public void start() {
        if (!_isRunning) {
            _startTime = System.nanoTime();
            _isRunning = true;
        }
    }

    public void stop() {
        if (_isRunning) {
            _elapsedTime += System.nanoTime() - _startTime;
            _isRunning = false;
        }
    }

    public void reset() {
        _elapsedTime = 0;
        if (_isRunning) {
            _startTime = System.nanoTime();
        }
    }

    public boolean isRunning() {
        return _isRunning;
    }

    public long getElapsedTimeNanos() {
        if (_isRunning) {
            return System.nanoTime() - _startTime;
        }
        return _elapsedTime;
    }

    public long getElapsedTimeMillis() {
        return getElapsedTimeNanos() / 1000000L;
    }

    // Private Members
    private boolean _isRunning = false;
    private long _startTime = 0;
    private long _elapsedTime = 0;
}
于 2012-11-20T16:48:16.843 回答