115

I want to get the current UTC time in millis. I searched google and got some answers that System.currentTimeMillis() does returns UTC time. but it does not. If I do following:

long t1 = System.currentTimeMillis();
long t2 = new Date().getTime();
long t3 = Calendar.getInstance().getTimeInMillis();

all three times are almost same ( difference is in milli seconds due to calls ).

t1 = 1372060916
t2 = 1372060917
t3 = 1372060918

and this time is not the UTC time instead this is my timezone time. How can i get the current UTC time in android?

Ruchira Gayan Ranaweera
  • 34,993
  • 17
  • 75
  • 115
g.revolution
  • 11,962
  • 23
  • 81
  • 107
  • 5
    Returns the current system time in milliseconds since January 1, 1970 00:00:00 UTC – Blackbelt Jun 24 '13 at 08:29
  • 2
    http://docs.oracle.com/javase/1.4.2/docs/api/java/lang/System.html#currentTimeMillis%28%29 – Marco Forberg Jun 24 '13 at 08:30
  • thats the question. what does it returns? utc time or it adjusts the time zone? if it does returns UTC time then t1 and t2, t3 should not be same as t2 and t3 does return your time zone time. – g.revolution Jun 24 '13 at 08:30
  • 3
    long t3 = Calendar.getInstance(TimeZone.getTimeZone("UTC")).getTimeInMillis(); – Blackbelt Jun 24 '13 at 08:32
  • 3
    The above link says "See the description of the class Date for a discussion of slight discrepancies that may arise between "computer time" and coordinated universal time (UTC)." and in java.util.Date documentation you find: "Although the Date class is intended to reflect coordinated universal time (UTC), it may not do so exactly, depending on the host environment of the Java Virtual Machine" -> so it may be possible that your machine returns non-UTC time – Marco Forberg Jun 24 '13 at 08:33
  • 5
    @g.revolution: It's "the number of milliseconds since January 1, 1970 00:00:00 UTC" - how would you expect that to adjust for a time zone? Your local time zone doesn't affect how many milliseconds have occurred since that epoch. – Jon Skeet Jun 24 '13 at 08:35

3 Answers3

159

All three of the lines you've shown will give the number of milliseconds since the unix epoch, which is a fixed point in time, not affected by your local time zone.

You say "this time is not the UTC time" - I suspect you've actually diagnosed that incorrectly. I would suggest using epochconverter.com for this. For example, in your example:

1372060916 = Mon, 24 Jun 2013 08:01:56 GMT

We don't know when you generated that value, but unless it was actually at 8:01am UTC, it's a problem with your system clock.

Neither System.currentTimeMillis nor the value within a Date itself are affected by time zone. However, you should be aware that Date.toString() does use the local time zone, which misleads many developers into thinking that a Date is inherently associated with a time zone - it's not, it's just an instant in time, without an associated time zone or even calendar system.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • 6
    So basically, that is to say that this function returns the same value if called at the same time from within different time zones, regardless of the host's clock, correct? – Phillip Aug 21 '13 at 01:35
  • 29
    Man this makes me wish the world would (could) adopt a single time zone. Who cares if the number on the clock is 00:00 or 08:00 when the big bright thing appears in the sky? The countless hours of otherwise productive time wasted on this historical relic makes my blood boil... – corsiKa Oct 21 '15 at 03:37
  • Related to this, note that the underlying call to the OS clock function has a documented 'drift' of several milliseconds. Java has a 'high performance timer' if the intention is to get a highly precise duration of an operation (timing when a task starts and finishes, the delta being the elapsed amount of time). See: https://docs.oracle.com/javase/7/docs/api/java/lang/System.html#nanoTime() – Darrell Teague Apr 14 '16 at 15:12
  • @JonSkeet if toString() internally use timezone how could I built string from it without timezone. Actually I am generating file in REST server which has filename exactly of midnight time value ex "1551139200.json"(February 26, 2019 12:00:00 AM) and that need to be accessed from android app once device's System.currentTimeMillis() returns exact time. – kiranking Feb 26 '19 at 05:00
  • @kiranking: Use `Date.getTime()` to find the milliseconds-since-Unix-epoch time, divide by 1000 (as that filename is in *seconds* since the Unix epoch) and just format that integer as a string. – Jon Skeet Feb 26 '19 at 06:53
  • @JonSkeet If i modified to local clock in Android lets say for future time then, all three methods will return future timestamp which – Tomer Mor Sep 25 '19 at 14:33
  • @TomerMor: Yes, if you make your clock inaccurate, then anything using that clock will be inaccurate. I think that's to be expected. – Jon Skeet Sep 25 '19 at 14:35
  • @JonSkeet So if user modified the local clock there is no way to know that ? – Tomer Mor Sep 25 '19 at 14:48
  • @TomerMor: Not using `System.currentTimeMillis`, no. You could use an NTP library or similar. I don't believe this question is really about that scenario though. – Jon Skeet Sep 25 '19 at 14:52
  • @corsiKa That would be a source of much greater frustration though :) Like hearing someone from a far away place say "I wake up at 11:00" we would always have to painfully account for that person's location to figure out something as simple as if he's an early bird or a night owl – Varvara Kalinina May 09 '23 at 19:47
  • @VarvaraKalinina No system is perfect, but 1) we already deal with that on a global basis 2) easily solved by doing away with AM/PM which don't really help and 3) is nowhere near as difficult to manage as international trade!! – corsiKa May 21 '23 at 06:13
2

I can confirm that all three calls could depend on the local time, considering the epoch, not the Date.toString() or any similar method. I've seen them depend on local time in specific devices running Android 2.3. I haven't tested them with other devices and android versions. In this case, the local time was set manually.

The only reliable way to get an independent UTC time is requesting a location update using the GPS_PROVIDER. The getTime() value of a location retrieved from NETWORK_PROVIDER also depends on local time. Another option is ping a server that returns a UTC timestamp, for example.

So, what I do is the following:

public static String getUTCstring(Location location) {
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
    String date = sdf.format(new Date(location.getTime()));
    // Append the string "UTC" to the date
    if(!date.contains("UTC")) {
        date += " UTC";
    }
    return date;
}
jlhonora
  • 10,179
  • 10
  • 46
  • 70
  • 3
    System.currentTimeMillis() returns a UTC based value. As to the 'precision' or accuracy of the operating system clock is concerned, while certainly this affects the result, is not in any way related to the system or Java environment time-zone value. – Darrell Teague Apr 14 '16 at 15:14
  • @DarrellTeague I insist, I saw different values in a specific Huawei device. So no, it doesn't always returns the correct UTC time (discarding accuracy differences) – jlhonora Apr 14 '16 at 15:17
  • The OP's question was about a Java class timezone usage. This was not about hardware or the accuracy of the returned time value. Simply put, the JVM gets its time from the (abstract) operating "system clock" (which varies by operating system in terms of how it functions). See also: http://www.drdobbs.com/embedded-systems/measuring-execution-time-and-real-time-p/193502123 and "C" implementations on operating systems https://www.chemie.fu-berlin.de/chemnet/use/info/libc/libc_17.html – Darrell Teague Apr 21 '16 at 13:57
0

Just answering the title question, "does System.currentTimeMillis() return UTC time?" ...

Yes. The Java API documentation actually says it's UTC:

currentTimeMillis
...
Returns: the difference, measured in milliseconds, between the current time and
midnight, January 1, 1970 UTC.
                          ^^^

Although I do have slight doubts which might be why this question hasn't been answered so directly.

The currentTimeMillis() value is derived from the hardware clock on the system board powered by a battery. The actual value can be set to anything but the only really sane thing to do is to set it to the EPOCH relative to UTC so that the device is not bound to a particular timezone (devices frequently travel and transmit data across timezones).

However, the hardware clock can be changed and in the past it was not uncommon for it to be set to local time. I'm sure there are reasons for people to still use local time today.

If you happen to be using Linux you can check to see if your machine's hardware clock is using local time or UTC:

# timedatectl
               Local time: Sat 2023-06-17 11:34:51 EDT
           Universal time: Sat 2023-06-17 15:34:51 UTC
                 RTC time: Sat 2023-06-17 15:34:51
                Time zone: America/New_York (EDT, -0400)
System clock synchronized: yes
              NTP service: active
          RTC in local TZ: no
                           ^^

I don't know if there is a scenario where currentTimeMillis() would return the a local time based value if the hardware clock was set to a local TZ. My feel is that the operating system abstracts these things and Java just asks the OS. So if System.currentTimeMillis() does not return a UTC value, it's because the OS is not configured correctly.

So for most intents and purposes, yes, System.currentTimeMillis() should return the same value across time zones (minus the usual drift, leap seconds, ...).

squarewav
  • 383
  • 2
  • 8