The java function System.currentTimeMillis() apparently returns the number of seconds since 1st January 1970. However, according to wikipedia.org/wiki/Leap_second, since 1972 there have been 25 leap seconds. This means the actual number of seconds since 1st January 1970 has been 25 more than a naive calculation would suggest. Does System.currentTimeMillis() do the naive calculation and ignore the leap seconds?
Officially, it's up to the OS and implementation - at least for Date. From the docs of java.util.Date:
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. Nearly all modern operating systems assume that 1 day = 24 × 60 × 60 = 86400 seconds in all cases. In UTC, however, about once every year or two there is an extra second, called a "leap second." The leap second is always added as the last second of the day, and always on December 31 or June 30. For example, the last minute of the year 1995 was 61 seconds long, thanks to an added leap second. Most computer clocks are not accurate enough to be able to reflect the leap-second distinction.
I suspect you'll find that although your computer clock is roughly aligned to UTC, that's done via NTP or the like correcting the clock periodically, rather than the OS really implementing leap seconds.
I believe the JRE libraries typically do assume the 86400-second day. It makes life so much simpler, and if you're going to correct for an inaccurate system clock anyway, you might as well correct for leap seconds that way too.
You really want to work out what you're interested in. If you need a way of representing dates and times which use leap seconds, the standard Java libraries may not work well for you. Even JSR-310 no longer supports leap seconds as far as I can tell (which is a very sensible decision for most developers).
POSIX requires that the system clock not admit the existence of leap seconds. MS Windows cannot guarantee the quality (nor existence) of the system clock hardware, and it has eschewed guarantee of 1-second accuracy. Java cannot easily do anything that the underlying system refuses to do. The operating systems are hamstrung by the history of the international regulations that result in one IEEE standard (PTP) that requires leap seconds and another (POSIX) that denies them.
One easy way to check if leap seconds are accounted for or not is to compute the number of seconds elapsed since the Epoch for 00:00 on any given day in the current year.
If that number of seconds is congruent to 00 modulo 60, then the leap seconds are not accounted for as in 2013 you should have a modulus of 25 (to account for the past 25 leap seconds).
I did a small experiment on javarepl:
java> new Date(1000L * 86400 * (365 * 4 + 1) * 12)
java.util.Date res0 = Mon Jan 01 00:00:00 UTC 2018
As you can see, a simple "naive" arithmetics that just regards leap year, but not leap seconds, is used. No extra seconds are added or subtracted.
Update:
Same for the new Instant class:
java> Instant.ofEpochMilli(1000L * 86400 * (365 * 4 + 1) * 12)
java.time.Instant res0 = 2018-01-01T00:00:00Z
Looking at the Javadoc for currentTimeMillis(), it referes to the documentation of the Date class, which has this to say:
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. Nearly all modern operating systems assume that 1 day = 24 × 60 × 60 = 86400 seconds in all cases. In UTC, however, about once every year or two there is an extra second, called a "leap second." The leap second is always added as the last second of the day, and always on December 31 or June 30. For example, the last minute of the year 1995 was 61 seconds long, thanks to an added leap second. Most computer clocks are not accurate enough to be able to reflect the leap-second distinction.
So to answer your question: Yes, leap seconds are accounted for.
Related
When I use System.currentTimeMillis() to measure the time, is it safe?
E.g. When a time-shift happens (summer->winter time) will this produce an error?
No, System.currentTimeMillis() returns the number of elapsed milliseconds since the Unix epoch (midnight at the start of January 1st 1970, UTC). This does not depend on your local time zone at all.
In other words, if you call it once per second, it will always increase by about 1000 (the "about" is only due to clock accuracy and the impossibility of the calls being exactly 1 second apart). It doesn't matter if your local time zone changes its offset from UTC, or if you even change your whole time zone - that will be irrelevant.
In theory, leap seconds make all of this trickier - but in practice most applications can get away with notionally sticking their fingers in their ears and saying "I'm not at home to Mr Leap Second."
System.currentTimeMillis() will return the milliseconds since epoch (1/1/1970 00:00:00). How those are interpreted is a completely different story (and summer/winter time as well as timezone belong to the interpretation part). So yes, it would be save.
Running the following code:
String s = "1914-07-20T00:00:00+0200";
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ");
System.out.println(df.parse( s ));
I get this result:
Sun Jul 19 23:34:52 EET 1914
(notice the date and hour)
It's probably one of those time adjustments that took place to get the sun to be overhead at noon. These took place around that time as the world got smaller and local time zones were being replaced by more universal ones. 25 minutes could well be such an adjustment. You would have to look at the record of time zone adjustments for eastern Europe from then to now.
An alternate way to check this is to put this in a loop and see it it works right in 1924 and 1934 and so forth until now. At some point, if its such an adjustment, it might start working and you could narrow it down to a particular time at which all times after work as expected and all times before don't. Though, to be sure, there could be a sequence of adjustments. 10 minutes here and 7 minutes there that add up the 25 minutes.
Note
This page (http://www.prokerala.com/travel/timezones/EET?mode=history) shows the GMT offset as 1.64444 in 1901 and 2 in 1920. That's 39:52 minutes and seconds.
This page (http://home.tiscali.nl/~t876506/TZworld.html) is about the global tz database and shows a LMT (local mean time) of 1:34:52 for Europe/Athens which is theoretically supposed to be +2:00. I'm not quite sure what that has to do with it but it seems a strange coincidence to be exactly what OP is seeing. (I also found that joda-time uses the LMT offset for any dates prior to the first entry in the "official" timezone data file.
Hello I am trying to create a teacher utility to port over to android OS. However I am running into a little trouble. I would like to create a class called Period. This class would contain the start and end time of that period. ie. Period one starts at 7:45 and ends at 8:45. I would also like to have a method for time left in period. for example it is now 8:10 and there are 35 minutes left. I am able to get the current time from System.currentTimeMillis(). However I am having trouble trying to figure out the best way to store the start and end time of the periods. i have taken a look at the Calendar class in Java and it seems like time is always tied to a date as well as a time. This does not seem to make seance for my application since the end time of the period happens on multiple days and not just on one particular date. Any help understanding this would be a great help. Thanks all
If your goal is to be able to compare the start and end time of the period with the current time, then you need a way to compute the date and time of the period's bounds for today.
So get a Calendar instance for today, set its time to 7:45, and compare the time of the calendar with the current time (same for the upper bound, of course).
To represent each bound, you could simply use an int for the hours and a second int for the minutes.
Check out the JodaTime library. The DateTime object has what you want.
Take a look at JodaTime.
Specifically, Period: http://joda-time.sourceforge.net/key_period.html
Calendar is a king of wrapper around the class Date which has mostly deprecated functions. I've heard that the JodoTime API is great for comparing two timestamps (http://joda-time.sourceforge.net/).
One way to store the start and end time for the periods would be to instantiate an ArrayList of dates so you can compare any given time to the lesson periods.
From what I can tell, you should store the time as a number of seconds (optionally milliseconds) from last midnight. Thus, your period one, 7.45, starts at 45*60 (45 minutes * 60 seconds per minute) + 7*60*60 (7 hours times minutes times seconds!) = 2 700 + 25 200 = 27 900.
Do the same calculation for your end date, and as long as they begin and end on the same day, you can easily subtract the difference and thus get the interval in between. If they do not happen on the same date, then Java's time and date classes are both excellent and a must. These classes essentially work the same algorithm, but do not count the seconds from "last midnight", instead they count the amount of milliseconds from the UNIX epoch time (1 January 1970).
In Joda, if I print
DateTime(GregorianChronology.getInstance())
.withYear(1970)
.withMonthOfYear(1)
.withDayOfMonth(1)
.withHourOfDay(0)
.withMinuteOfHour(0)
.withSecondOfMinute(0)
.withMillisOfSecond(0).getMillis();
I see 18000000 (this also happens to be 1/4th of MILLIS_PER_DAY, FWIW).
What I don't understand is that if the milliseconds represents the offset from the epoch which is defined as Jan-1970-01-01, then shouldn't the milliseconds be 0?
The epoch is Jan-1970-01-01 GMT. The instance you have, obviously has a different DateTimeZone. In fact it lookds like you're at GMT+5. (18000000 millis = 5 hours)
I believe the issue is related to the way Java dates include the time zone as part of there calculations.
For me, this means I'm +10 hours ahead of the epoc.
Try creating a Date/Time value that is set to 0 GMT.
The "epoch" is a specific and universal instant, a point in the universe time (like, say the moment in which the Apollo XI landed on the moon). This reference point can be represented differently in different countries (and a martian could also represent it with his own calendar). For example, for the people in England (GMT), that's the moment in which the hands of their clocks marked "00:00:00" and their (Gregorian) calendars marked "1/1/1970"; but that's just an example.
The line
DateTime(GregorianChronology.getInstance()).withYear(1970).withMonthOfYear(1)
.withDayOfMonth(1).withHourOfDay(0).withMinuteOfHour(0)
.withSecondOfMinute(0).withMillisOfSecond(0)
gives you the instant in which the clocks and the calendars in your country marked "00:00:00 1970-01-01". That's, in general, a different instant.
I try to calculate a List with times. But using LocalTime from Joda Time I can only get a 24 hours.
What is the right class to use to get e.g. 34hours 20minutes 14 seconds?
Thanks in advance
You may be look for Period:
A period in Joda-Time represents a period of time defined in terms of fields, for example, 3 years 5 months 2 days and 7 hours. This differs from a duration in that it is inexact in terms of milliseconds. A period can only be resolved to an exact number of milliseconds by specifying the instant (including chronology and time zone) it is relative to.
If you are looking to add times, so you can tell how many hours/seconds... are in between, you would maybe be better off if you use plain miliseconds calculations, add all the miliseconds and then subsrtact the miliseconds from your first time, and there you are, you have the span in miliseconds...