学习使用环境变量、JVM参数和TimeZone类来设置JVM使用的默认时区。
1.概述
任何应用程序的用户都希望看到他们本地时区的日期和时间戳,没有人喜欢在他们的头脑中进行时区调整。
为了向用户显示本地日期的时间戳,JVM使用的时区必须是可预测的,最好是固定的。这使得应用程序的单元测试和集成测试,关于特定时区的时间戳,变得容易和更可靠。
在分布式部署模型中,设置JVM的时区更有必要,因为应用程序在全球多个数据中心运行,而每个数据中心的JVM可能是不同的时区。
- 默认情况下,JVM会从操作系统中读取时区信息,并将其存储在
TimeZone类中。 - 要获得JVM中设置的默认时区,使用方法
TimeZone.getDefault()。 - 要获得所有支持的时区列表,使用方法
TimeZone.getAvailableIDs()。 - Java使用tz数据库的命名规则。
2.如何设置JVM的时区
2.1.设置环境变量'TZ
设置环境变量TZ ,JVM可以用它来获取JVM中的默认时区。
在Linux中,我们可以使用export 命令。
export TZ="Asia/Kolkata"
在windows中,我们可以使用Control Panel -> Date and Time -> Change Time Zone -> Select your preferred time zone 选项来设置所讨论的时区。
设置完环境变量后,我们可以在我们的Java程序中验证它。
TimeZone timezone = TimeZone.getDefault();
System.out.printf("DisplayName = %s, ID = %s, offset = %s",
timeZone.getDisplayName(),timeZone.getID(),timeZone.getRawOffset());
程序输出。
DisplayName = Coordinated Universal Time, ID = UTC, offset = 0
2.2.设置JVM参数或系统属性 "user.timezone
如果设置环境变量是不可能的,那么我们可以使用JVM参数-Duser. timezone 来设置时区。 不要把时区值用双引号括起来。
java -Duser.timezone=UTC com.app.Main
//or
java -Duser.timezone=Asia/Kolkata com.app.Main
同样的参数,我们可以使用系统属性"user.timezone" 来设置。
System.setProperty("user.timezone", "UTC");
现在我们可以在Java程序中验证更新的时区值。
TimeZone timezone = TimeZone.getDefault();
System.out.printf("DisplayName = %s, ID = %s, offset = %s",
timeZone.getDisplayName(),timeZone.getID(),timeZone.getRawOffset());
程序输出。
DisplayName = Coordinated Universal Time, ID = UTC, offset = 0
2.3.TimeZone.setDefault()
另一种类似于设置系统属性的方法是直接在TimeZone 类中设置默认时区。
TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
验证时区值将得到与前面技术相同的结果。
3.JVM如何解决时区问题
默认情况下,Java日期和时间类从操作系统中获取时区信息。JVM解析操作系统时区的方式,在每个操作系统中都是不同的。
获取机器时区的一种方法是来自系统时钟,并在时钟中修改所需的时区。但这种方法在资源按需提供的云环境中是不可能的。
我们可以通过运行时的JVM参数和应用程序中的Java语句来改变时区的值。
请注意。
TZ环境变量(如果有的话)会覆盖系统的默认时区。- JVM参数
-Duser.timezone覆盖TZ环境变量。 TimeZone.setDefault()覆盖 参数。-Duser.timezone
4.最佳实践
- 不要依赖机器的默认区域。始终使用上述技术之一来指定你想要的/期望的时区。
- 一个应用程序可能有对时区敏感的时间戳,在云环境中部署应用程序后,该应用程序可能在我们不知情的情况下被转移到不同的数据中心。为了避免这些不一致,建议使用
-Duser.timezone系统属性来设置JVM时区。 - 如果我们的要求是不仅JVM要使用一个时区,而且它的所有子进程(如IDE)也要使用一个时区,那么设置TZ环境变量就更有意义。一个很好的例子是在启动Eclipse时设置这个变量,然后你在所有由Eclipse启动的JVM中都有这个变量。
- 我们应该倾向于使用较长的时区名称而不是三个字母的ID。有一些短的IDS在多个时区之间是重复的。例如,
IST可以是印度标准时间、爱尔兰标准时间或以色列标准时间。
5.总结
在本教程中,我们学习了如何设置Unix和Windows操作系统中JVM使用的默认时区。
作为一个最佳实践,总是在JRE级别或应用程序级别设置默认时区,以获得一致和预期的时间戳。
学习愉快!!
