Java Internationalization: Time Zones
Jakob Jenkov |
This text examines how to work with time zones in Java.
When users of a system, e.g. a web application, have different time zones, it can be challenging to manage dates and time in the system in manner that looks consistent to all users. I will take a look at this issue in this text.
UTC
UTC is short for Coordinated Universal Time (Universal Time Coordinated ?). UTC is the time in the UK time zone (like Greenwich Mean Time).
Time Zones
All time zones are calculated as offsets to UTC time. For instance, the time zone in Copenhagen, Denmark is UTC + 1 meaning UTC time plus one hour.
Daylight Savings
UTC time is independent of daylight savings time. That means, that in the summer time, the time in Copenhagen, Denmark is UTC + 2, meaning UTC time plus two hours.
Store Dates and Times in UTC
If your application needs to store dates and time internally, for instance in a database, convert it to UTC time before storing it. It is a lot easier to search for a given date and time, when all dates and times are stored in UTC. If the dates and times were stored in different time zones in a database, it would be hard to search for all dates before or after a certain date. You would need to convert the dates and time zones while searching, in order to compare to the date of the search criteria. This doesn't really work.
This diagram illustrates the storing of dates and time in UTC:
Store dates and time in UTC. |
When storing dates and time in UTC, it is easy to convert them to any local time zone, as the diagram also hints.
Converting Time Zones
When a user types in a date and time, they usually do so in their own time zone. If a user in another time zone need to look at that date and time, that user would often like to see that date and time converted to his own time zone.
In Java you can convert between time zones using the java.util.Calendar
class.
Here is an example:
Calendar calendar = new GregorianCalendar(); calendar.setTimeZone(TimeZone.getTimeZone("Etc/UTC")); calendar.set(Calendar.HOUR_OF_DAY, 12); System.out.println("UTC: " + calendar.get(Calendar.HOUR_OF_DAY)); System.out.println("UTC: " + calendar.getTimeInMillis()); calendar.setTimeZone(TimeZone.getTimeZone("Europe/Copenhagen")); System.out.println("CPH: " + calendar.get(Calendar.HOUR_OF_DAY)); System.out.println("CPH: " + calendar.getTimeInMillis()); calendar.setTimeZone(TimeZone.getTimeZone("America/New_York")); System.out.println("NYC: " + calendar.get(Calendar.HOUR_OF_DAY)); System.out.println("NYC: " + calendar.getTimeInMillis());
First you create a GregorianCalendar
instance (Calendar subclass).
Second you set the time zone to UTC. You should always set the time zone before
setting the time. If you don't, the time you set (e.g. hour of day) may be interpreted
as being in the time zone of the Calendar
instance. When you later change
the time zone, the hour of day etc. changes your time (hour of day). So start with the
time zone, then set the time (millis, hour of day etc.).
Third you set the time. You can set the time in any given time zone (just set the time zone first).
Fourth you can change the time zone to the desired target time zone. After changing time zone you can see that the hour of day etc. may change. This example prints out the hour of day after changing time zone to two different time zones, both different from UTC.
The output printed from this example would be:
UTC: 12 UTC: 1363351520548 CPH: 13 CPH: 1363351520548 NYC: 8 NYC: 1363351520548
Please not, that the Calendar.getTimeInMillis()
always returns the time in UTC, regardless
of the time zone set on the Calendar
instance. As you can see from the output above,
the hour of day varies between the three time zones, but the time in milliseconds is the same.
Available Time Zone ID's
As you saw in the example, you get the time zone from the java.util.TimeZone
class.
To do so, you need to know the ID of the time zone. Here is an example:
TimeZone timeZone = TimeZone.getTimeZone("Europe/Copenhagen") calendar.setTimeZone(timeZone);
In this example the time zone ID is Europe/Copenhagen
.
You can obtain a list of the available time zone ID's using the TimeZone.getAvailableIDs()
.
Here is an example:
String[] availableIDs = TimeZone.getAvailableIDs(); for(String id : availableIDs) { System.out.println("id = " + id); }
This examples obtains all the available time zone ID's, and then prints them to System.out
.
You can then find the ones matching your needs.
I have described the java.util.TimeZone
class in more detail in my Java Date Time tutorial,
in the TimeZone class.
Tweet | |
Jakob Jenkov |