1. Overview
The users of our applications can be demanding when it comes to timestamps. They expect our applications to detect their time zones automatically, and display timestamps in the correct time zone.
In this tutorial, we'll take a look at several ways we can modify the time zone of the JVM. We'll also learn about some of the pitfalls associated with managing the time zone.
2. Introduction to Time Zone
By default, the JVM reads time zone information from the operating system. This information gets passed to the TimeZone class, which stores the time zone and calculates the daylight saving time.
We can call the method getDefault, which will return the time zone where the program is running. Furthermore, we can obtain a list of supported time zone IDs from the application using TimeZone.getAvailableIDs().
When naming the time zone, Java relies on the naming convention of the tz database.
3. Changing the Time Zone
In this section, we're going to take a look at several ways we can change the time zone in the JVM.
3.1. Setting an Environment Variable
Let's begin by seeing how we can use an environment variable to change the time zone. We can add or modify an environment variable TZ.
For example, in Linux-based environments, we can use the export command:
export TZ="America/Sao_Paulo"
After setting the environment variable, we can see that the time zone of our running application is now America/Sao_Paulo:
Calendar calendar = Calendar.getInstance(); assertEquals(calendar.getTimeZone(), TimeZone.getTimeZone("America/Sao_Paulo"));
3.2. Setting a JVM Argument
An alternative to setting an environment variable is setting the JVM argument user.timezone. This JVM argument takes precedence over the environment variable TZ.
For example, we can use the flag -D when we run our application:
java -Duser.timezone="Asia/Kolkata" com.company.Main
Likewise, we can also set the JVM argument from the application:
System.setProperty("user.timezone", "Asia/Kolkata");
We can now see that the time zone is Asia/Kolkata:
Calendar calendar = Calendar.getInstance(); assertEquals(calendar.getTimeZone(), TimeZone.getTimeZone("Asia/Kolkata"));
3.3. Setting the Time Zone From the Application
Finally, we can also modify the JVM time zone from the application using the TimeZone class. This approach takes precedence over both the environment variable and the JVM argument.
Setting the default time zone is easy:
TimeZone.setDefault(TimeZone.getTimeZone("Portugal"));
As expected, the time zone is now Portugal:
Calendar calendar = Calendar.getInstance(); assertEquals(calendar.getTimeZone(), TimeZone.getTimeZone("Portugal"));
4. Pitfalls
4.1. Using Three-letter Time Zone IDs
Even though it's possible to use three-letter IDs to represent the time zone, it's not recommended.
Instead, we should use the longer names, as the three-letter IDs are ambiguous. For example, IST could be either India Standard Time, Irish Standard Time or Israel Standard Time.
4.2. Global Settings
Note that each of the above approaches is setting the timezone globally for the entire application. In modern applications, though, setting the timezone is often more nuanced than that.
For example, we probably need to translate time into the end user's timezone, and so a global timezone wouldn't make much sense. If a global timezone isn't needed, consider specifying the time zone directly on each date-time instance. Either ZonedDateTime or OffsetDateTime is a handy class for this.
5. Conclusion
In this tutorial, we explained several ways to modify the time zone of the JVM. We saw that we could either set a system-wide environment variable, change a JVM argument or modify it programmatically from our application.
As usual, all the examples used in this article are available over on GitHub.