簡體   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