How to Set the JVM Time Zone – 如何设置JVM的时区

最后修改: 2019年 12月 23日

中文/混合/英文(键盘快捷键:t)

1. Overview

1.概述

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.

在本教程中,我们将看一看我们可以修改JVM时区的几种方法。我们还将了解与管理时区相关的一些陷阱。

2. Introduction to Time Zone

2.时区介绍

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.

默认情况下,JVM会从操作系统中读取时区信息。该信息被传递给TimeZone类,该类存储时区并计算日光节约时间

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().

我们可以调用方法getDefault,,它将返回程序运行的时区。此外,我们可以使用TimeZone.getAvailableIDs()从应用程序中获得一个支持的时区ID列表。

When naming the time zone, Java relies on the naming convention of the tz database.

当命名时区时,Java依赖于tz数据库的命名惯例。

3. Changing the Time Zone

3.改变时区

In this section, we’re going to take a look at several ways we can change the time zone in the JVM.

在这一节中,我们将看一下我们可以在JVM中改变时区的几种方法。

3.1. Setting an Environment Variable

3.1.设置一个环境变量

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.

让我们首先看看我们如何使用环境变量来改变时区。我们可以添加或修改一个环境变量TZ.

For example, in Linux-based environments, we can use the export command:

例如,在基于Linux的环境中,我们可以使用export命令。

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:

设置完环境变量后,我们可以看到,我们正在运行的应用程序的时区现在是America/Sao_Paulo:

Calendar calendar = Calendar.getInstance();
assertEquals(calendar.getTimeZone(), TimeZone.getTimeZone("America/Sao_Paulo"));

3.2. Setting a JVM Argument

3.2.设置一个JVM参数

An alternative to setting an environment variable is setting the JVM argument user.timezone. This JVM argument takes precedence over the environment variable TZ.

设置环境变量的另一个方法是设置JVM参数user.timezone这个JVM参数优先于环境变量TZ

For example, we can use the flag -D when we run our application:

例如,我们可以在运行我们的应用程序时使用标志-D

java -Duser.timezone="Asia/Kolkata" com.company.Main

Likewise, we can also set the JVM argument from the application:

同样地,我们也可以从应用程序中设置JVM参数

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

3.3.从应用程序中设置时区

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.

最后,我们还可以使用TimeZone类从应用程序中修改JVM的时区。这种方法比环境变量和JVM参数都要优先考虑。

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. 陷阱

4.1. Using Three-letter Time Zone IDs

4.1.使用三字母时区标识

Even though it’s possible to use three-letter IDs to represent the time zone, it’s not recommended.

尽管可以使用三个字母的ID来表示时区,但是不推荐使用

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.

相反,我们应该使用较长的名称,因为三个字母的ID是模糊的。例如,IST可以是印度标准时间、爱尔兰标准时间或以色列标准时间。

4.2. Global Settings

4.2.全局设置

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.

例如,我们可能需要将时间翻译成最终用户的时区,所以全局时区就没有什么意义了。如果不需要全局时区,可以考虑在每个日期-时间实例上直接指定时区。ZonedDateTimeOffsetDateTime是一个方便的类。

5. Conclusion

5.总结

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.

在本教程中,我们解释了修改JVM时区的几种方法。我们看到,我们可以设置一个系统范围内的环境变量,改变一个JVM参数,或者从我们的应用程序中以编程方式修改它。

As usual, all the examples used in this article are available over on GitHub.

像往常一样,本文中使用的所有例子都是GitHub上提供的。