繁体   English   中英

如何确保明确指定 java 系统属性 `user.timezone`?

[英]How to ensure that java system property `user.timezone` is explicitly specified?

我想确保我的 Java 程序始终由明确指定的user.timezone属性运行。 我将-Duser.timezone=XXX作为命令行设置传递。

但是,当我完全忽略该系统属性,然后在我的程序中检查System.getProperty("user.timezone")的值时,它不是null ,而是包含系统时区。 所以,我不能终止我的程序,因为该属性的值永远不会是 null。

我知道我可以使用自定义系统属性名称(例如tz )来接受时区 ID,然后在我的代码中执行TimeZone.setDefault(System.getProperty("tz")) ,但我更喜欢使用系统属性user.timezone ,旨在用于此原因。

有什么方法可以使用user.timezone系统属性来实现我所需要的吗?

明确指定时区作为方法调用的参数

依赖 JVM 当前的默认时区本质上是不可靠的。 JVM 中任何应用程序的任何线程中的任何代码都可以随时通过调用TimeZone.setDefault来更改默认值。 这样的调用会立即影响依赖于该默认值的所有其他代码。

相反,请始终明确指定您希望/期望的时区。

此外, TimeZone已经过时,几年前被 JSR 310 中定义的现代java.time类所取代。特别是ZoneIdZoneOffset 您可以将这些类的 object 作为可选参数传递给所有相关方法。

ZoneId z = ZoneId.of( "Africa/Casablanca" ) ;
ZonedDateTime now = ZonedDateTime.now( z ) ;

UTC 是一个真正的时间

在服务器上,通常最佳实践是将主机操作系统和 JVM 的默认时区设置为 UTC(与 UTC 的偏移量为零)。

您的大部分业务逻辑、日志记录和调试也都应该使用 UTC。

只需要一个时区:

  • 本地化显示给用户时。
  • 在特定业务规则要求的情况下。

顺便说一句,该属性user.timezone未列为 Java 11 中的标准默认属性之一。

我非常同意 Basil Bourque 的回答:您的解决方案是编写代码,使其独立于 JVM 默认时区。 同样如评论中所述,当通过 JDBC 4.2(或更高版本)将 java.time 类型与您的 SQL 数据库一起使用时,没有默认时区干扰。

此外,从我读过的驱动程序倾向于使用数据库 session 时区,而不是 JVM 默认时区。 您可能需要搜索数据库文档和 JDBC 驱动程序文档,以了解控制 session 时区的方法。

但是,要按要求回答您的问题:

    String userTimezoneProp = System.getProperty("user.timezone");
    boolean timezonePropertyEmpty = userTimezoneProp == null || userTimezoneProp.isEmpty();
    if (timezonePropertyEmpty) {
        System.err.println("You must set the user.timezone property to the same time zone as the database time zone.");
        System.exit(-1);
    }

只有您必须在执行任何使用默认时区的操作之前执行此操作。 一旦执行了这样的操作,JVM 将向操作系统查询默认时区并相应地设置系统属性(如果成功)。

根据文档System.getProperty()应该为尚未设置的系统属性返回null 在这个例子中,我的 Java 返回了一个空字符串。 所以我将这两种可能性都考虑在内。 这对于user.timezone可能是特别的。 我没有找到任何提到它的文档。 我仍然不保证该方法是防弹的。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM