java 时区 不正确_Java中的时区不匹配
我在美國的Ubuntu服務器中運行一個Java應用程序,并配置了CEST時區。
如果我在終端中運行Date命令,它將以CEST Zone時間返回日期-這是完美的。
但是在Java中,如果我運行以下代碼
System.out.println (new Date ());
它給了我EDT時間。 我缺少什么配置。
參見stackoverflow.com/questions/3010035/
從控制臺中獲取的顯示中解釋日期對象時必須小心,因為它們是使用運行該程序的VM的默認TimeZone格式化的(默認情況下是從OS的時區繼承的)。
當然,您可以根據Jesper的回答提供您自己的TimeZone。但是在這樣做的同時,我強烈建議您使用IANA時區標識符(例如America / New_York)而不是EST。之所以如此,是因為具有"標準"的縮寫未考慮日光節約。
因此,如果僅在控制臺上打印日期對象,而沒有得到預期的結果,則很有可能將服務器時區設置為錯誤的值,或者將OS設置為錯誤的時區。
要更改JVM時區,可以在啟動時使用此參數
-Duser.timezone="America/New_York"
tl; dr
世界標準時間:
Instant.now() ? ?// Instantiate an object capturing the current moment in UTC.
.toString() ?// Generate a String representing textually that date-time value using standard ISO 8601 format.
2018-03-16T00:57:34.233762Z
分區:
ZonedDateTime.now( ZoneId.of("Africa/Tunis" ) ) ?// Instantiate an object representing the current moment with a wall-clock time seed by people in a particular region (time zone).
.toString() ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? // Generate a String representing textually that date-time value using standard ISO 8601 format wisely extended to append the name of the time zone in square brackets.
2018-03-16T01:57:34.233762+01:00[Africa/Tunis]
細節
Shailendra的答案是正確的。
另外,在Question中看到的Date類是麻煩的舊日期時間類的一部分,這些類現在已被遺留,完全被java.time類所取代。
java.util.Date的替換為java.time.Instant。 Instant類表示UTC時間軸上的時刻,其分辨率為納秒(最多十進制的九(9)位數字)。
Instant::toString?始終使用UTC
調用舊類的Date::toString方法時,其作者選擇的不幸行為是動態應用JVM的當前默認時區。這不會造成混亂。幸運的是,現代類無需添加任何時區即可說出簡單的事實:Instant始終位于UTC中。
Instant.now().toString()
2018-03-16T00:57:34.233762Z
該字符串格式是標準的ISO 8601格式。最后的Z是Zulu的縮寫,表示UTC。
CEST Zone time
沒有名為CEST的時區。這樣的3-4個字母名稱是偽區域。它們不是標準化的。它們不是唯一的(!)。而是使用continent/region格式的正確時區。
ZoneId z = ZoneId.of("Europe/Paris" ) ;
您可以通過將ZoneId應用于Instant以獲得ZoneDateTime,從UTC調整到這樣的時區。
Instant instant = Instant.now() ;
ZonedDateTime zdt = instant.atZone( z ) ;
zdt.toString(): 2018-03-16T01:57:34.233762+01:00[Europe/Paris]
或使用快捷方式ZonedDateTime.now。
ZonedDateTime zdt = ZonedDateTime.now( z ) ;
您也可以將ZonedDateTime調整為另一個時區。注意,java.time使用不可變對象。因此,在調整過程中,我們會基于原始對象得到一個新的獨特對象,但又不會干擾原始對象。
ZoneId zNewYork = ZoneId.of("America/New_York" ) ;
ZonedDateTime zdtNewYork = zdt.withZoneSameInstant( zNewYork ) ;
zdtNewYork.toString(): 2018-03-15T20:57:34.233762-04:00[America/New_York]
非常清楚,Instant,zdt和zdtNewYork是三個單獨的對象,它們代表時間軸上的同一時刻,同一點。相同的時刻,不同的時鐘時間。
I have a Java Application running in my Ubuntu Server in USA and configure CEST Time Zone
僅供參考,一般來說,服務器默認時區的最佳做法是UTC。
更重要的是,服務器操作系統和JVM的當前默認時區應與Java應用程序無關。
不要隱式依賴JVM的當前默認時區,而應始終明確指定所需/期望的時區。如上面的代碼所示,將可選的ZoneId參數傳遞給各種java.time方法。
(順便說一下,Locale的同上-始終指定所需/預期的語言環境,而不是隱式依賴于當前默認值。)
關于java.time
java.time框架內置于Java 8及更高版本中。這些類取代了麻煩的舊版舊式日期時間類,例如java.util.Date,Calendar和SimpleDateFormat。
現在處于維護模式的Joda-Time項目建議遷移到java.time類。
要了解更多信息,請參見Oracle教程。并在Stack Overflow中搜索許多示例和說明。規格為JSR 310。
您可以直接與數據庫交換java.time對象。使用與JDBC 4.2或更高版本兼容的JDBC驅動程序。不需要字符串,不需要java.sql.*類。
在哪里獲取java.time類?
Java SE 8,Java SE 9和更高版本
內置的
標準Java API的一部分,具有捆綁的實現。
Java 9添加了一些次要功能和修復。
Java SE 6和Java SE 7
java.time的許多功能在ThreeTen-Backport中都被反向移植到Java 6和7。
安卓系統
更高版本的Android捆綁了java.time類的實現。
對于早期的Android(<26),ThreeTenABP項目改編了ThreeTen-Backport(如上所述)。請參閱如何使用ThreeTenABP…。
ThreeTen-Extra項目使用其他類擴展了java.time。該項目為將來可能在java.time中添加內容提供了一個試驗場。您可能會在這里找到一些有用的類,例如Interval,YearWeek,YearQuarter等。
您說服務器配置為位于CEST時區,但是根據Java,默認時區為EDT。 Java從操作系統獲取默認時區,因此您的服務器可能未正確設置為CEST。
如果要在特定時區中打印日期,請使用DateFormat并在其上設置時區:
DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss Z");
df.setTimeZone(TimeZone.getTimeZone("CET"));
System.out.println(df.format(new Date()));
注意:根據我的Java(Java 7u45),CEST不是有效的時區。您是說"英語四級考試"嗎? (CEST是CET的夏季變體,但是如果您使用CET,則Java將在適當的時候自動在夏季顯示時間)。
總結
以上是生活随笔為你收集整理的java 时区 不正确_Java中的时区不匹配的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 小企业财务软件哪个最好用,该如何选择?
- 下一篇: lstm轴承寿命预测