Подтвердить что ты не робот

Как измерить прошедшее время

У меня есть 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 секунды.
4b9b3361

Ответ 1

Когда игра начинается:

long tStart = System.currentTimeMillis();

Когда игра заканчивается:

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

Ответ 2

В соответствии с документами Android SystemClock.elapsedRealtime() является рекомендуемой основой для интервалов общего назначения. Это связано с тем, что, согласно документации, elapsedRealtime() is guaranteed to be monotonic, [...], so is the recommend basis for general purpose interval timing.

SystemClock документация имеет хороший обзор различных временных методов и применимые случаи применения для них.

  • 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(...).

Также, вместо использования Timer, вы можете захотеть изучить использование TimerTask, этот класс предназначен для того, что вы хотите делать. Единственная проблема заключается в том, что он ведет обратный отсчет, а не вверх, но это можно решить простым вычитанием.

Ответ 3

Еще лучше!

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

Прочитайте документацию о nanoTime()!

Ответ 4

Есть много способов достичь этого, но наиболее важным фактором для измерения прошедшего времени является использование 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);
    }
}