2015-02-11 104 views
2

我的Web應用程序在Apache Tomcat 7.0上運行。我們正在調用java util日曆來獲取服務器的日期時間。問題是,如果系統時區發生更改,java日曆將繼續以「舊」時區的日期時間運行。 Tomcat使用os時區更改tomcat需要重啓

JDK是 - JDK1.6

你能告訴我們爲什麼需要tomcat的重啓,以反映新的時區?

+0

類似於:[* Java 1.7日光節約變化無法識別*](https://stackoverflow.com/q/29383690/642706) – 2018-03-05 23:23:57

+0

類似於:[*在未啓動服務器的情況下處理Tomcat中的夏令時*] (https://stackoverflow.com/q/49113219/642706) – 2018-03-05 23:36:00

回答

1

最好的方法是在Java中使用日期時總是指定時區。或者在Tomcat中與

-Duser.timezone = GMT

參數指定。其他方式Tomcat從系統啓動時加載時區。

0

我認爲需要重新啓動的原因是,沒有人願意爲在主動運行並連接到互聯網時穿越不同時區的服務器服務。有趣的用例。顯然很少見。很稀少。

將您的服務器設置爲UTC,使用UTC啓動tomcat,然後將您的應用程序配置爲在您遇到的任何時區格式化時間 - 問題已解決。

1

tl; dr

儘可能以UTC工作。

Instant.now() // Capture current moment in UTC. 

永遠不要依賴主機操作系統,JVM或數據庫的當前默認時區設置。明確指定所需/預期的時區。

ZoneId z = ZoneId.of("Africa/Tunis") ; 
ZonedDateTime zdt = instant.atZone(z) ; // Same moment, same point on the timeline, different wall-clock time. 

決不依賴於服務器的時區設置

真正的問題是,你根據在你無法控制,並且可以在任何時刻改變的方面有一些代碼:JVM的當前默認時間區。

您不應該編寫依賴於系統默認時區的代碼。相反,請始終明確指定所需的/預期的時區作爲傳遞給相關類的可選參數。

問題是,如果系統時區已更改,java日曆會一直以「舊」時區的日期時間運行。

主機操作系統(OS)有其自己的當前默認時區設置和自己的時區定義(tzdata)。同上你的數據庫服務器;如果日期時間處理比較複雜,例如Postgres,它可能在內部存儲它自己的tzdata。你的JVM也有它自己當前的默認時區設置和它自己的時區定義(tzdata)。當定義更改感興趣的時區時,應通過軟件產品版本更新或特定於tzdata的更新程序更新所有三個位置中的tzdata

我知道啓動時默認啓用的所有JVM實現,以將它自己的當前默認時區設置爲主機操作系統的默認時區。啓動JVM之後,更改主機操作系統時區設置應該對您的JVM沒有影響,至少在我見過的Oracle和OpenJDK實現中不會有影響。

我們調用java util calendar來獲取服務器的日期時間。

切勿使用麻煩的舊的遺留日期時間類,如Date & Calendar。這些已完全被java.times類取代。

請問爲什麼tomcat需要重啓以反映新的時區?

我猜你的網絡應用程序不適當地緩存UTC的偏移量而不是總是使用時區。與UTC的偏移距UTC僅爲幾個小時 - 分鐘的位移。時區更多,是過去,現在和將來對特定地區人民所使用的抵消的變化的歷史。所以總是使用時區而不是單純的偏移量。有關更多詳細信息,請參閱my Answer以獲得類似的問題。

continent/region的格式指定一個proper time zone name,如America/MontrealAfrica/Casablanca,或Pacific/Auckland。切勿使用3-4字母縮寫,如ESTIST,因爲它們是而不是真正的時區,不是標準化的,甚至不是唯一的(!)。

ZoneId z = ZoneId.of("America/Montreal") ; 
ZonedDateTime zdt = ZonedDateTime.now(z) ; 

如果您想使用JVM的當前默認時區,請詢問並作爲參數傳遞。如果省略,則隱式應用JVM的當前默認值。更好的是明確的,因爲在運行時的任何時候,默認可以通過JVM中任何應用程序的任何線程中的任何代碼在任何時刻改變

ZoneId z = ZoneId.systemDefault() ; // Get JVM’s current default time zone. 

UTC

一般來說除非最好的區域是由你的業務邏輯或用戶界面需要UTC始終工作。你應該學會以UTC來思考,工作,記錄,存儲和交換數據。在作爲程序員或管理員工作時忘記自己的狹隘時區。

Instant類表示UTC中的時間軸上的一個時刻,分辨率爲nanoseconds(小數點後最多九(9)位數字)。

Instant instant = Instant.now() ; // Capture current moment in UTC. 

關於java.time

java.time框架是建立在Java 8和更高版本。這些類代替了日期時間類legacy,如java.util.Date,Calendar,& SimpleDateFormat

Joda-Time項目,現在在maintenance mode,建議遷移到java.time類。請參閱Oracle Tutorial。並搜索堆棧溢出了很多例子和解釋。規格是JSR 310

你可調換java.time直接對象與數據庫。使用符合JDBC 4.2或更高版本的JDBC driver。無需字符串,不需要java.sql.*類。

從何處獲取java.time類?

ThreeTen-Extra項目與其他類擴展java.time。這個項目是未來可能增加java.time的一個試驗場。您可以在這裏找到一些有用的類,如Interval,YearWeek,YearQuartermore