(Level: Beginner/Intermediate)
Few things in the
Java language (or any computer language, for that matter) generate as many questions, or get misused as often as TIME, which is surprising, because computer time really is
very simple; it's us puny humans - or rather, our
perception of time - that complicates things.
This page is meant to give you a quick overview of how to deal with displaying times, and hopefully to prevent a few common traps that people fall into.
.
Lesson 1: Java Time is the same - ALWAYS
Whenever you write:
or:
you are storing a
numeric value containing the current time according to the machine's internal clock.
And if you do it simultaneously on 50 different machines around the world, it will store
the same value (OK, it could be out by a few seconds) even though CLOCKS in each of those countries show a different time.
Why?
Because computer time uses a
universal start point (called the Epoch): in Java's case, 00:00:00 on the 1st of January, 1970 GMT (and that 'GMT' is
very important) - and ALL time values are
offsets from this point - either negative or positive - in milliseconds.
Thus, all computer (and Java) times contain an implicit
date. Indeed, the basic class for storing times in Java is
Date - specifically, java.
util.Date (there is also a java.
sql.Date class).
.
Lesson 2: So what's the problem?
Simply put: US.
Even in these days of global communication, we live in our own little world, which includes our own little timezone, and assume that everybody else does the same.
So, when we ask "what's the time?", we're not asking what the
actual time is, we're asking: "what time
of day is it HERE?".
And that's because
clock time has nothing to do with actual time (as you'll soon find out if you ever experience jet-lag); it's a convenience for us
diurnal humans so that we can deal with where the sun is: "Oh, the sun is overhead; it must be about noon. Time for lunch."
Moreover, the whole business of regional time zones is quite recent. Before the advent of railways, the local church (or Mosque) was the sole arbiter of "what time it is" - and that was mainly to make sure that everybody got to prayers on time.
Computers have no such parochial issues. To them, time is simply a nice long chain of milliseconds from a
fixed point (the 'Epoch' described above) - and it's the
same chain for everyone, anywhere in the world.
Furthermore, there are
network services that allow computers to know where they are and what time it is (the computer's internal clock is good, but even it needs to be corrected every so often) so that they can display the correct
CLOCK time accurately.
Anyone who's taken a laptop across timezones will probably have seen the phenomenon: you turn it on at your destination and it shows the WRONG clock time (usually the time where you came from); connect it to the Internet and, hey presto, within a few seconds it's displaying the correct time again.
Remember: Timezones are a
human invention. They have nothing to do with actual time.
.
Lesson 3: Content and Display
Hopefully, I've now convinced you that, for Java (and outside the laws of relativity), time is
the same wherever you are in the world. So if I create a Java time value of 1000 (1000 milliseconds
after the Epoch) it will equate to 00:00:01 1/1/1970
GMT.
What it will NOT do is
display the same around the world.
And this point doesn't just apply to time.
Whenever you write Java classes, you need to be very clear to distinguish what they contain from what they look like .
.
To display times in human-readable form in Java, you need a
DateFormat object; and the easiest one to use is
SimpleDateFormat.
The following code sets up a fairly typical SimpleDateFormat field:
This will display a time in the form: 2012/01/01 13:45:00 WET, where the timezone will depend on where your machine is located.
Now, suppose you set up the time described above as follows:
and display it using the format object above:
.
Now, you send that SAME CODE to four different machines in London, Paris, New York and Tokyo.
In London it will display
in Paris it will display
in New York it will display
and in Tokyo it will display
because even though the
content (ie, the time) is the same (1000L), the
rules for display are different.
And you know what? You don't have to do a darn thing:
SimpleDateFormat does it for you. And
that's the main point of this lesson (and, in fact, this page):
You don't need to change Java times in order to have them display properly.
If you do, you are simply undoing (and usually
fouling up) all the work that those nice guys at Sun did when they created the SimpleDateFormat class for you.
.
It's probably worth adding that you can also use the class to display a time for timezones that are
different to your own, so:
will display
EPlus1 according to
Paris time.
.
OTHER STUFF
Since this page is about
time, rather than dates, I won't go into the whole mess of different calendars. Suffice to say they are yet another human invention that confuses our notions of time. As of the writing of this page, there is only one
Calendar offered by the standard Java classes:
GregorianCalendar - and
you should get to know it.
It should also be added that Calendars in Java are concerned with storing and manipulating dates and times, NOT
displaying them; and if you look carefully at the API, you'll find that there is nothing in them about display.
.
However, it's probably worth mentioning
Daylight Savings Time - yet another human pitchfork in the nice, tidy, ordered world of computer time.
Simple rule:
Don't worry about it.
DST is only a factor when you need to
display a
clock time, and the classes already mentioned will take care of it;
including displaying the correct clock time when DST in in effect.
Otherwise?
Deal with time as a value; or, if you prefer, as (Epoch + millisecond-offset).
If you always remember that time in Java is a value - and that it's the same for
everyone - you're unlikely to run into trouble. It's when you start "overthinking" things that problems crop up.
.
Joda Time
The fact is that Java's date/time API is
bad (and I say that as someone who loves the language).
The classes, other than Date, are clumsy, difficult to follow (Calendar alone contains 49 different fields and 52 methods; and it's not even a
concrete class) and scattered all over the place. This is also reflected in the documentation which, while describing how each class works, doesn't really give you any insight as to
how you're supposed to use them.
Joda Time to the rescue. It's an open-source project that was set up by a bunch of chaps with the express purpose of
making time easier, and includes all sorts of goodies, including complete working calendars for all the major religions, and the ability to deal with time
intervals (the
difference between two times) directly.
It has also been around for quite a while, so you don't need to worry that you're plunging into "bleeding edge" technology, and it's very compatible with the existing Java time classes.
Indeed, many of its features were suggested to Sun/Oracle as
JSR-310 for inclusion into Java Version 7, but were turned down. More fool them, I say.
.
FAQs
is UTC the same as GMT?
Correct answer: No.
Simple answer: Yes.
For anything that you're likely to be dealing with, you can assume that they are the same. Another term for the same time is "Zulu time", often used by the military - particularly sailors.
Another important thing to know about UTC/GMT/Zulu time is that none of them involves Daylight Savings.
EVER.
.
What about leap seconds?
Simple answer: Don't sweat them.
The fact is that if you know about leap seconds, you're probably past the point where you need this page. Furthermore, they are very rare (only 39
have been added since 1961) and they always occur on June 30th or Dec. 31st. at midnight
GMT (again, that 'GMT' is
very important).
There is only
one situation where you might have to worry about them: if you need an
accurate timing for a duration that spans a leap-second; and if that's the case, you should use
System.nanoTime() rather than
System.currentTimeMillis(). Indeed, you should
always use
nanoTime() if you want accurate timings.
And if the duration is so long that using
nanoTime() is impractical? You're stuffed.
Simply put:
there is no way to register leap seconds with System.currentTimeMillis(), because they are removed before you ever get to see the value. Joda Time (see above)
does allow you to include leap-seconds, but even it might return a bad value if you're unlucky enough to have a duration that starts or ends ON a leap-second.
FURTHER READING
The first thing you should do is read the APIs for ALL the classes mentioned in this document (they should all be linked). And read them carefully.Also read up on the Locale and TimeZone classes.Unix_time - this is the time system emulated by Java, and the linked article goes into more depth about the mechanics, if you're interested.The JavaDatesFaq also talks about some of these, and other, topics.
CategoryWinston