-3

I am building application which is time sensitive i.e. some tasks need to be completed within certain time. There are multiple ways to get the time i.e. System.currentTimeMillis() and gpsLocation.getTime(). I don't want to use System.currentTimeMillis() because user can manually change the time. What about gpsLocation.getTime()? I have observed that in some areas, device is unable to get GPS location. Which timestamp should I use then?

Location Timestamp

open fun onLocationChanged(location: Location?) {
    ellapsedTime = location.getTime()
}

I am detecting whether user has changed the Auto Time and Timezone settings with the following code:

val isAutoTime = Settings.Global.getInt(activity!!.getContentResolver(), Settings.Global.AUTO_TIME)
        val isAutoTimezone = Settings.Global.getInt(activity!!.getContentResolver(), Settings.Global.AUTO_TIME_ZONE)

What approach should I use to get the timestamps?

What is missing in question?

Please comment what is the missing part? Or it may be the case that you are not understanding the question/concern. I am writing for best approach to compare the timestamps. I have added pros and cons of using System.currentTimeinMillis() and location.getTime(). As application is time dependant so if user plays around with time settings then I should be able to compare accurate timestamps rather than system time.

Mustansar Saeed
  • 2,730
  • 2
  • 22
  • 46
  • @OleV.V.: This is mentioned in question desription `I don't want to use System.currentTimeMillis() because user can manually change the time` – Mustansar Saeed Dec 26 '19 at 13:04

1 Answers1

1

From what you have told us it seems that System.nanoTime() would be a good option. Contrary to System.currentTimeMillis(), System.nanoTime() is not affected by the user setting the system clock of the device manually. So even if they do, within your program you can reliable calculate elapsed time based on System.nanoTime().

System.nanoTme() promises to measure elapsed time reliably as long as the JVM is running. So as long as your program is running, you have reliable measurements. They say that the method really gives you the number of nanoseconds since the device was booted, and if this is so, you can also measure across runs of your program as long as the device isn’t rebooted. There is no guarantee of the latter though, and it may be different with the next Android version.

For a demonstration of the difference see this snippet:

    long millis0 = System.currentTimeMillis();
    long nanos0 = System.nanoTime();

    System.out.println("Type a line to continue");
    new Scanner(System.in).nextLine();

    long millis1 = System.currentTimeMillis();
    long nanos1 = System.nanoTime();

    System.out.println("Elapsed time according to System.currentTimeMillis(): " + Duration.ofMillis(millis1 - millis0));
    System.out.println("Elapsed time according to System.nanoTime(): " + Duration.ofNanos(nanos1 - nanos0));

I ran it on my computer and adjusted the computer clock an hour forward in the middle. The session looked like:

Type a line to continue
I have now adjusted the computer clock
Elapsed time according to System.currentTimeMillis(): PT1H16.169S
Elapsed time according to System.nanoTime(): PT28.359865564S

So from System.currentTimeMillis() it incorrectly looked like 1 hour 16.169 seconds had elpased. System.nanoTime() told the truth: only 28.359865564 seconds had gone by.

Link: Documentation of System.nanoTime()

Ole V.V.
  • 81,772
  • 15
  • 137
  • 161