如何衡量经过的时间

时间:2013-03-06 13:39:28

标签: java android

我有一个10和20的问题游戏。我需要计算用户完成游戏后经过的时间。

Timer T=new Timer();
T.scheduleAtFixedRate(new TimerTask() {         
    @Override
    public void run() {
        runOnUiThread(new Runnable()
        {                
            public void run()
            {
                countdown.setText(""+count);
                count++;                
            }
        });
    }
}, 1000, 1000);

我用这个来阻止计数器:

T.cancel();

现在我需要两件事:

  • 如何计算经过时间并将其存储在变量中的方法
  • 我需要最终值为双倍,例如最终得分是:15.49秒。

5 个答案:

答案 0 :(得分:72)

游戏开始时:

long tStart = System.currentTimeMillis();

游戏结束时:

long tEnd = System.currentTimeMillis();
long tDelta = tEnd - tStart;
double elapsedSeconds = tDelta / 1000.0;

答案 1 :(得分:48)

根据Android docs SystemClock.elapsedRealtime()是通用间隔时间的推荐基础。这是因为根据文档,elapsedRealtime()is guaranteed to be monotonic, [...], so is the recommend basis for general purpose interval timing.

SystemClock documentation概述了各种时间方法及其适用的用例。

  • SystemClock.elapsedRealtime()SystemClock.elapsedRealtimeNanos()是计算通用时间的最佳选择。
  • SystemClock.uptimeMillis()System.nanoTime()是另一种可能性,但与推荐的方法不同,它们不包括深度睡眠时间。如果这是你想要的行为,那么他们可以使用。否则坚持使用elapsedRealtime()
  • 远离System.currentTimeMillis(),因为这将返回“挂墙”时钟时间。由于挂钟时间可能向前或向后跳跃,因此不适合计算经过时间。像NTP客户端这样的很多东西都会导致挂钟时间跳跃和歪斜。这将导致基于currentTimeMillis()的经过时间计算并不总是准确的。

游戏开始时:

long startTime = SystemClock.elapsedRealtime();

游戏结束时:

long endTime = SystemClock.elapsedRealtime();
long elapsedMilliSeconds = endTime - startTime;
double elapsedSeconds = elapsedMilliSeconds / 1000.0;

此外,Timer()是尽力而为计时器,并不总是准确的。因此在游戏持续时间内会有累积的计时错误。要更准确地显示过渡时间,请定期检查System.currentTimeMillis()作为发送到setText(...)的时间的基础。

此外,您可能希望使用TimerTask来代替使用Timer,而是针对您要执行的操作而设计此类。唯一的问题是它倒计时而不是向上,但这可以通过简单的减法来解决。

答案 2 :(得分:10)

更好!

long tStart = System.nanoTime();
long tEnd = System.nanoTime();
long tRes = tEnd - tStart; // time in nanoseconds

阅读关于nanoTime()的documentation

答案 3 :(得分:1)

有许多方法可以实现这一点,但是测量经过时间的最重要考虑因素是使用System.nanoTime()TimeUnit.NANOSECONDS作为时间单位。 我为什么要这样做?好吧,这是因为System.nanoTime()方法返回了高分辨率的时间源,距离某个参考点(即Java虚拟机的启动)以纳秒为单位。

  

此方法只能用于测量经过时间,与系统或挂钟时间的任何其他概念无关。

出于相同的原因,建议避免使用System.currentTimeMillis()方法来测量经过时间。此方法返回wall-clock时间,该时间可能会因许多因素而改变。这对您的测量结果不利。

  

请注意,虽然返回值的时间单位为毫秒,但值的粒度取决于基础操作系统,并且可能更大。例如,许多操作系统都以几十毫秒为单位测量时间。

因此,这里有一个基于System.nanoTime()方法的解决方案,另一种使用Guava的解决方案,最后一个是Apache Commons Lang

public class TimeBenchUtil
{
    public static void main(String[] args) throws InterruptedException
    {
        stopWatch();
        stopWatchGuava();
        stopWatchApacheCommons();
    }

    public static void stopWatch() throws InterruptedException
    {
        long endTime, timeElapsed, startTime = System.nanoTime();

        /* ... the code being measured starts ... */

        // sleep for 5 seconds
        TimeUnit.SECONDS.sleep(5);

        /* ... the code being measured ends ... */

        endTime = System.nanoTime();

        // get difference of two nanoTime values
        timeElapsed = endTime - startTime;

        System.out.println("Execution time in nanoseconds   : " + timeElapsed);
    }

    public static void stopWatchGuava() throws InterruptedException
    {
        // Creates and starts a new stopwatch
        Stopwatch stopwatch = Stopwatch.createStarted();

        /* ... the code being measured starts ... */

        // sleep for 5 seconds
        TimeUnit.SECONDS.sleep(5);
        /* ... the code being measured ends ... */

        stopwatch.stop(); // optional

        // get elapsed time, expressed in milliseconds
        long timeElapsed = stopwatch.elapsed(TimeUnit.NANOSECONDS);

        System.out.println("Execution time in nanoseconds   : " + timeElapsed);
    }

    public static void stopWatchApacheCommons() throws InterruptedException
    {
        StopWatch stopwatch = new StopWatch();
        stopwatch.start();

        /* ... the code being measured starts ... */

        // sleep for 5 seconds
        TimeUnit.SECONDS.sleep(5);

        /* ... the code being measured ends ... */

        stopwatch.stop();    // Optional

        long timeElapsed = stopwatch.getNanoTime();

        System.out.println("Execution time in nanoseconds   : " + timeElapsed);
    }
}

答案 4 :(得分:0)

从Java 8开始,您可以尝试以下操作:

import java.time.*;
import java.time.temporal.ChronoUnit;

Instant start_time = Instant.now();
// Your code
Instant stop_time = Instant.now();

System.out.println(Duration.between(start_time, stop_time).toMillis());

//or

System.out.println(ChronoUnit.MILLIS.between(start_time, stop_time));