2

I'm working on an Android app and I have this problem.

For example, if I delete a file (operation A) and I receive a new file (operation B), I want to know how much time has passed between the two operations. I want it to work also if, in between, the user changes the date of the system, turns off the internet or restarts the device.

I know that exists SystemClock.elapsedRealtime() but its value restarts from zero if the user restarts the device.

I cannot use System.currentTimeMillis() because it changes if user changes the date.

I cannot get a date from the internet.

Thanks

Ole V.V.
  • 81,772
  • 15
  • 137
  • 161
Gigi
  • 359
  • 2
  • 16
  • 2
    you can try using `System.currentTimeMilis()`, or get the time from the internet – Vladyslav Matviienko Feb 08 '18 at 09:06
  • How are you going to know the real time if the computer clock is changed, and the machine is disconnected from the internet? – SeverityOne Feb 08 '18 at 09:09
  • If you need to keep this time shift even when the device is turned off inbetween and you don't have internet, you will have to write the time down somewhere when he does operation A, then read it when he recreates a file – Turtle Feb 08 '18 at 09:10
  • There's also [`TimingLogger`](https://developer.android.com/reference/android/util/TimingLogger.html). However, if the user restarts the device you will lose the start time so you need some kind of persistent storage. – simon Feb 08 '18 at 09:10
  • `System.currentTimeMillis()` should do it, as it measures time in relation to the same date - write the value to shared prefs or something after A and read it and compare during B. – PPartisan Feb 08 '18 at 09:11
  • 1
    @SeverityOne He doesn't need to know the real time, just the time elapsed. – Turtle Feb 08 '18 at 09:11
  • @PPartisan Doesn't `System.currentTimeMillis()` refers to the time _since the last power-on_ ? – Turtle Feb 08 '18 at 09:12
  • 1
    @Nathan Nope, it's time since 01/01/1970 - [`System::currentTimeMillis`](https://developer.android.com/reference/java/lang/System.html#currentTimeMillis()) – PPartisan Feb 08 '18 at 09:13
  • @PPartisan Oh, didn't know that. Thanks for pointing it out! – Turtle Feb 08 '18 at 09:35
  • 1
    It sounds a bit like you are asking the impossible. You may take a look at [I want to get current time in Java but without the Internet and without the system time](https://stackoverflow.com/questions/31222397/i-want-to-get-current-time-in-java-but-without-the-internet-and-without-the-syst). – Ole V.V. Feb 08 '18 at 12:18

2 Answers2

1

Use System.currentTimeMillis(). It gets the time elapsed since the epoch (January 1st 1970).

You need a global var:

long start;

on the first action:

start = System.currentTimeMillis();

Since it's the time from the epoch, restarting the device isn't going to change it (i.e. System.nanoTime would be reset). However, as with most other methods, it isn't safe from changing the time of the device. If someone changes the time on the device back to the start of the epoch, you will experience some problems.

Note that there is no way to get the exact time since the event happened if the time is changed. I.e. if the user does operation A, waits a few hours, sets the clock back to a few hours ago, there's basically no offline ways you can check that. If you use a server, you can get the time from that, but there's not any way to get the accurate, unmodified time difference offline that's tamper proof (where tampering is changing the time).

TL;DR: System.currentTimeMillis is an offline option, but it isn't safe from time changing. If you need it to show the right time difference independently of the user changing the time of the device, use a server.

EDIT:

If you can't use System.currentTimeMillis or get a time from the internet, you can't measure the time at all. AFAIK, every Java/Android API relies on System.currentTimeMillis (or get the current time some other way). Example: the Date class can be converted to a Long representing the current time in milliseconds. For long-term timing, you either have to use System.currentTimeMillis or a server. System.nanoTime restarts when the JVM restarts. So does elapsedRealTime.

Zoe
  • 27,060
  • 21
  • 118
  • 148
0

You just need to grab the time from somewhere before and after the activities you want to time and take one from the other. This uses the system clock but you could equally get the real time from some other source

    long startTime = System.currentTimeMillis();
    // Your code
    System.out.println("Operation took " + (System.currentTimeMillis() - startTime) + " milliseconds");
Old Nick
  • 995
  • 9
  • 19
  • Your two lines are two different operations that I have in two different classes that can be executed in two different moments...maybe the second one is executed after two months. If the user changes the date this doesn't work. – Gigi Feb 08 '18 at 09:15
  • Yes Gigi, I posted it before you made your edit where you included those extra requirements. – Old Nick Feb 08 '18 at 09:23