4

I am trying to implement a timer, it may be used for short (seconds) events, or longer (hours, etc) events.

Ideally it should persist over periods when the CPU is off, for example, battery has died. If I set the start time using System.currentTimeMillis() and end time using the same function, it works in almost all cases, except during periods like leap seconds, leap years, daylight savings time changes, etc... Or, if the user just changes the time (I've verified this). This is on an Android system, btw.

Instead, if I used System.nanoTime(), in addition to potentially being more accurate, it won't have the usual "hard time" issues with time changes, etc. My question is, does System.nanoTime() measure nanoseconds from some arbitrary time, in "hard time"? I'm not sure what the proper term is, but for example, will System.nanoTime() ran at X, then X+1 hour later, the system is shut off (dead battery on Android device, for example), then X+10 hours, the system is started, will running System.nanoTime() at this point return 10 hours? Or will it return 1 hour (since the "counter" that nanoTime uses may not be running when system is off/asleep?).

n00begon
  • 3,503
  • 3
  • 29
  • 42
Tony Tieger
  • 113
  • 2
  • 4
  • " it won't have the usual "hard time" issues with time changes," do not understand why you think that. All absolute measures of time will require interpretation by a higher level API to accurately translate into human time accounting for things like daylight savings. – Affe Jun 18 '12 at 22:19
  • What I mean is, I don't care about time accounting in absolute time. I just care about elapsed time. This application will be used like a cooking timer. If the user reboots, shuts down, adjusts the clock, etc, between start-stop of timer, the timer should still work. – Tony Tieger Jun 18 '12 at 22:36
  • It seems nanoTime() will allow user to adjust clock and still work, but not for reboots/shutdowns, while currentTimeMillis will work for reboots/shutdowns but not the user adjusting the clock. Was really hoping nanoTime() would work, since the definition of nanoTime says it's from an arbitrary origin time, was hoping this origin time is constant on one machine, and didn't change when machine was rebooted, etc... – Tony Tieger Jun 18 '12 at 22:37

2 Answers2

2

android.os.SystemClock.elapsedRealtime() - milliseconds since the system was booted including time spent in sleep state. This should be your best bet.

I dont think you can measure the switched off time in android.

For more info it might be better to check android system clock page. http://developer.android.com/reference/android/os/SystemClock.html

ppsreejith
  • 3,318
  • 2
  • 25
  • 27
  • Ahh, yes I've looked at that, it looks like a good solution. Would nanoTime() be more accurate? It seems like elapsedRealtime() is similar to nanoTime(), with the exception of milli versus nano precision, and that elapsedRealtime() has a set starting reference (system boot) versus arbitrary start reference. – Tony Tieger Jun 18 '12 at 23:09
  • 2
    From here: http://comments.gmane.org/gmane.comp.handhelds.android.platform/6874 it seems that System.nanoTime() uses clock_gettime() with CLOCK_MONOTONIC. The clock stops when the device goes into deep sleep, so nanoTime() won't work. I think elapsedRealtime() is the best solution, as it will only not work when system is off. I'll end up using this, thanks! – Tony Tieger Jun 18 '12 at 23:15
1

It is undefined:

"The value returned represents nanoseconds since some fixed but arbitrary origin time (perhaps in the future, so values may be negative). The same origin is used by all invocations of this method in an instance of a Java virtual machine; other virtual machine instances are likely to use a different origin."

For simplicity, we'll say when you run it at time X, the origin is X (this is allowed). That means it will return 0 then, and within the VM instance, time will then elapse at the same rate as a normal clock.

When you use Thread.sleep, that doesn't change the VM instance, so it isn't treated specially.

However, after the device is rebooted, you're in a different VM instance. Therefore, X is no longer guaranteed to be the origin.

Matthew Flaschen
  • 278,309
  • 50
  • 514
  • 539
  • Ahh, thanks, so it won't persist over machine shutdowns. The purpose of this timing function is to time anything, from start to stop. No guarantees what happens between start and stop (user can theoretically reboot machine, shut off machine for an hour, set system clock ahead an hour, etc). – Tony Tieger Jun 18 '12 at 22:32