简体   繁体   English

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

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

I want to be sure that my Java program is always run by explicitly specified user.timezone property.我想确保我的 Java 程序始终由明确指定的user.timezone属性运行。 I pass -Duser.timezone=XXX as a command-line setting.我将-Duser.timezone=XXX作为命令行设置传递。

However, when I omit that system property at all, and then in my program I check the value of System.getProperty("user.timezone") , it is not null , instead, it contains the system timezone.但是,当我完全忽略该系统属性,然后在我的程序中检查System.getProperty("user.timezone")的值时,它不是null ,而是包含系统时区。 So, I can't terminate my program, as the value of that property is never null.所以,我不能终止我的程序,因为该属性的值永远不会是 null。

I know that I can use a custom system property name(say tz ) to accept the timezone ID and then execute TimeZone.setDefault(System.getProperty("tz")) in my code, but I prefer to use the system property user.timezone , which is intended to be used for that reason.我知道我可以使用自定义系统属性名称(例如tz )来接受时区 ID,然后在我的代码中执行TimeZone.setDefault(System.getProperty("tz")) ,但我更喜欢使用系统属性user.timezone ,旨在用于此原因。

Is there any way to achieve what I need using user.timezone system property?有什么方法可以使用user.timezone系统属性来实现我所需要的吗?

Specify time zone explicitly as argument to method calls明确指定时区作为方法调用的参数

Relying on the JVM's current default time zone is inherently unreliable.依赖 JVM 当前的默认时区本质上是不可靠的。 Any code in any thread of any app within the JVM can, at any moment, change the default with a call to TimeZone.setDefault . JVM 中任何应用程序的任何线程中的任何代码都可以随时通过调用TimeZone.setDefault来更改默认值。 Such a call immediately affects all other code relying on that default.这样的调用会立即影响依赖于该默认值的所有其他代码。

Instead, always specify explicitly the time zone you desire/expect.相反,请始终明确指定您希望/期望的时区。

Also, TimeZone is obsolete, supplanted years ago by the modern java.time classes defined in JSR 310. Specifically, ZoneId and ZoneOffset .此外, TimeZone已经过时,几年前被 JSR 310 中定义的现代java.time类所取代。特别是ZoneIdZoneOffset You can pass an object of those classes as an optional argument to all the relevant methods.您可以将这些类的 object 作为可选参数传递给所有相关方法。

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

UTC is the one true time UTC 是一个真正的时间

On a server, generally the best practice is to set the default time zone of both the host OS and JVM to UTC (an offset-from-UTC of zero).在服务器上,通常最佳实践是将主机操作系统和 JVM 的默认时区设置为 UTC(与 UTC 的偏移量为零)。

And most of your business logic, logging, and debugging should all be in UTC as well.您的大部分业务逻辑、日志记录和调试也都应该使用 UTC。

A time zone should only be needed:只需要一个时区:

  • When localizing display to the user.本地化显示给用户时。
  • Where required by a particular business rule.在特定业务规则要求的情况下。

By the way, that property user.timezone is not listed as one of the standard default properties in Java 11.顺便说一句,该属性user.timezone未列为 Java 11 中的标准默认属性之一。

I very much agree with the answer by Basil Bourque: Your solution is to write your code so it is independent of a JVM default time zone.我非常同意 Basil Bourque 的回答:您的解决方案是编写代码,使其独立于 JVM 默认时区。 Also as mentioned in the comments, when using java.time types with your SQL database through JDBC 4.2 (or later), no default time zone interferes.同样如评论中所述,当通过 JDBC 4.2(或更高版本)将 java.time 类型与您的 SQL 数据库一起使用时,没有默认时区干扰。

Furthermore from what I have read drivers tend to use the database session time zone, not the JVM default time zone.此外,从我读过的驱动程序倾向于使用数据库 session 时区,而不是 JVM 默认时区。 You may want to search your database documentation and your JDBC driver documentation for ways to control the session time zone.您可能需要搜索数据库文档和 JDBC 驱动程序文档,以了解控制 session 时区的方法。

However to answer your question as asked:但是,要按要求回答您的问题:

    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);
    }

Only you must do this before doing any operations that use the default time zone.只有您必须在执行任何使用默认时区的操作之前执行此操作。 Once such an operation is performed, the JVM will query the operating system for a default time zone and set the system property accordingly (if successful).一旦执行了这样的操作,JVM 将向操作系统查询默认时区并相应地设置系统属性(如果成功)。

According to the documentation System.getProperty() should return null for a system property that has not been set.根据文档System.getProperty()应该为尚未设置的系统属性返回null My Java returned an empty string in this example.在这个例子中,我的 Java 返回了一个空字符串。 So I take both possibilities into account.所以我将这两种可能性都考虑在内。 It may be something special for user.timezone .这对于user.timezone可能是特别的。 I didn't find any documentation mentioning it.我没有找到任何提到它的文档。 I still do not guarantee that the method is bullet-proof.我仍然不保证该方法是防弹的。

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

相关问题 Java System.getProperty(“user.timezone”) 不起作用 - Java System.getProperty( “user.timezone” ) does not work 如何确定Java的user.timezone是否已被用户更改? - How to determine if java's user.timezone was altered by the user? System.setProperty(“user.timezone”,“America / Chicago”)之间的区别;和TimeZone.setDefault(TimeZone.getTimeZone(“America / Chicago”)); - Difference between System.setProperty(“user.timezone”, “America/Chicago”); and TimeZone.setDefault(TimeZone.getTimeZone(“America/Chicago”)); 如何将系统的时区转换为用户的时区 - How to convert system's timezone to user's timezone 如何从MySQL DATETIME转换为java.time.Instant并在系统默认时区显示给用户? - How do I convert from MySQL DATETIME to java.time.Instant and display to user in system default timezone? java泛型如何确保类型已指定注释? - java generic how to ensure type has specified annotation? 如何将时区转换为指定格式? - How convert Timezone into specified format? Java:如何从用户指定的文件进行扫描 - Java: How to scan from a user specified file 使用 Java 更改系统的时区 - Changing timezone of a system using Java 如何在 linux 操作系统中使用 Java 获取服务器时区信息 - How to get Server TimeZone Information using Java in linux operating system
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM