8

I know that System.currentTimeMillis() gives the time in milliseconds since the epoch and it is sensitive to the wall clock time of the system. I also know that it is not advisable to use System.currentTimeMillis() to calculate elapsed time in a program that measures time. Java library have provided System.nanoTime() for that purpose.

I have two specific questions for System.currentTimeMillis():

  1. Does it get affected by leap second adjustments? I think the answer is yes since the wall clock time of the system will be adjusted because of the leap second.
  2. Does it get affected when DST (DayLight Savings) is turned on/off ? What would happen when the time suddenly changes from 23:59 to 2:00? Since the system clock actually changes I would think that the answer is again yes but I would like to check with the community.
Pang
  • 9,564
  • 146
  • 81
  • 122
Geek
  • 26,489
  • 43
  • 149
  • 227
  • 1
    The system clock does not necessarily change at DST changes. Unix-like systems typically keep it at UTC. – kiheru Sep 15 '13 at 12:24
  • @kiheru So the system tray wouldn't show the adjusted time after a DST triggers? – Geek Sep 15 '13 at 12:36
  • 1
    The user visible time changes, but the hardware clock time is not changed. `currentTimeMillis()` on for example on [solaris](http://hg.openjdk.java.net/jdk7/hotspot/hotspot/file/9b0ca45cd756/src/os/solaris/vm/os_solaris.cpp) uses [gettimeofday()](http://pubs.opengroup.org/onlinepubs/009695399/functions/gettimeofday.html). That is the time since of the epoch, and is not dependent on the time zone. I don't know about windows. – kiheru Sep 15 '13 at 12:41
  • 1
    One thing that *can* change the time returned in surprising ways are time adjustments done by an NTP daemon (or manually). As a result the time difference of two subsequent `currentTimeMillis()` calls can be negative. – kiheru Sep 15 '13 at 12:52

2 Answers2

11

The value returned by System.currentTimeMillis() is the number of milliseconds that have elapsed since the epoch. This number of milliseconds is just that: a number of milliseconds.

Let's say that on a given day, your country has decided to go from 1:00 to 2:00 instantly, due to DST. Does that mean that 1 hour has elapsed between 1:00 and 2:00? No. 0 milliseconds have elapsed. Your country has simply decided that the millisecond value X was represented as 1:00, and that the millisecond X + 1 was represented at 2:00. The representation of the time doesn't change what milliseconds are.

JB Nizet
  • 678,734
  • 91
  • 1,224
  • 1,255
  • 2
    it is *not* the actual number of elapsed SI milliseconds unless TAI (or similar time scale) is used for `currentTimeMillis()` (unlikely). To get the actual number of elapsed milliseconds you need to add the difference in number of leap seconds between the events. It is especially clear if you try to find the difference between `2012-06-30T23:59:59Z` and `2012-07-01T00:00:00Z` -- `currentTimeMillis()` returns `1000` but the actual number is `2000`. – jfs Sep 15 '14 at 02:34
  • @J.F.Sebastian Good comment, but I would be careful with the term TAI which was known in this exact form AFTER 1970 - see also [details](http://time4j.net/javadoc-en/net/time4j/scale/TimeScale.html#TAI). This is based on the research work of Steve Allen. And JB Nizet has not talked about SI-seconds, just about "milliseconds" ;-) – Meno Hochschild Sep 15 '14 at 05:58
1

The clear answer to your two questions is: No, no.

In supplement to the answer of @ok about dst effects, System.currentTimeMillis() does not count leap seconds. In theory and practise it depends on the operational system. Since most OS and the Java VM included rather follow POSIX standard the consequence is (also by interoperability and behavioural compatibility issues) that leap seconds are not even allowed to have any effect on System.currentTimeMillis().

You can also easily verify this by comparing the value of System.currentTimeMillis() (divided by 1000) with your own calculation of SI seconds elapsed since 1972-01-01T00:00:00. The difference must be now 25 seconds.

UPDATE from the discussion below:

Leap seconds do not have effect on System.currentTimeMillis() in the long term (not counted), but maybe in the short term. I consider this as irrelevant however because this time source is not designed for achieving high accuracy and time stability.

The output of this time source is even subject to sudden changes up to minutes (for example if a pc was offline for a long time). And if people are going to use this time source and experience hard problems during a leap second then they will almost for sure also experience (harder) problems during any resync of this time source with an external time source like a NTP server.

Meno Hochschild
  • 42,708
  • 7
  • 104
  • 126
  • Ordinary Unix timestamp may repeat due to an intercalary leap second on some systems. Do you say that `currentTimeMillis()` is different (to avoid any effect)? – jfs Sep 15 '14 at 02:36
  • @J.F.Sebastian According to my own experiences `currentTimeMillis()` does not automatically repeat such timestamps during a leapsecond (resulting in different long-values for a short period), but the OS-kernel will set the timer back any arbitrary time (very) soon. So in long term the method does not count leap seconds - and must not count because of interoperability with other similar systems. As side note: NTP-servers repeat timestamps during a leap second - based on my own observation on 2012-07-01. – Meno Hochschild Sep 15 '14 at 04:30
  • you are describing Windows behavior that is configured as ntp client. btw, your calculation of elapsed seconds have to include TAI time (or equiv.) -- 35 seconds ahead of UTC at the moment. [UTC is not very well defined in 1970](http://hpiers.obspm.fr/eoppc/bul/bulc/UTC-TAI.history) – jfs Sep 15 '14 at 04:44
  • @J.F.Sebastian Agreed, UTC-scale was introduced in 1972 in radio signals so I used an approximation for the two years before. Let's just calculate the SI-seconds since 1972-01-01, and you will see that `System.currentTimeMillis()` does not count leap seconds. Very straight forward and clear. – Meno Hochschild Sep 15 '14 at 04:51
  • "have any effect" and "does not count" are not equivalent. Around and during leap seconds the timestamp may be affected depending on how the system clock takes into account leap seconds. – jfs Sep 15 '14 at 05:22
  • @J.F.Sebastian That is an infinitesimal fine hair to split ;-) Much more interesting is what happens in long term. And the method `System.currentTimeMillis()` is - also outside of any leapsecond events - completely subject to sudden changes up to several minutes!!! triggered by arbitrary syncs with NTP-servers for example (if the pc was a long time offline). No reliable time source at all. Users should really not care about leap seconds or any accuracy in context of this method as the OP had done. – Meno Hochschild Sep 15 '14 at 05:38
  • @J.F.Sebastian To clarify, I have the long term effect of leap seconds on `System.currentTimeMillis()` in mind which is reproducible if you at least sync the pc with NTP for a while to achieve down to 1ms accuracy. You and the OP have the short term effect in mind, but this is uninteresting for any computation purpose due to the unreliability of that time source. – Meno Hochschild Sep 15 '14 at 05:48
  • "That is an infinitesimal fine hair to split" -- **it is the question that OP asks** and that hair (the time during the leap seconds) may cost millions of dollars to deal with each time a leap second is introduced. Look at [my comment above](http://stackoverflow.com/questions/18812237/is-the-value-returned-by-system-currenttimeinmillis-affected-by-day-light-savi/18858740?noredirect=1#comment40428817_18812490): the difference `1000` and `2000` might be significant. There could be [issues](http://stackoverflow.com/q/11279076/4279). – jfs Sep 15 '14 at 06:00
  • @J.F.Sebastian Well, if it is so critical then why using this unreliable time source at all??? `System.currentTimeMillis()` is not designed for such use cases. The OP should rather have cared about the sudden changes of the output of that time source due to many other reasons. – Meno Hochschild Sep 15 '14 at 06:05