java 时区 不正确_Java中的时区不匹配
我在美國的Ubuntu服務(wù)器中運(yùn)行一個(gè)Java應(yīng)用程序,并配置了CEST時(shí)區(qū)。
如果我在終端中運(yùn)行Date命令,它將以CEST Zone時(shí)間返回日期-這是完美的。
但是在Java中,如果我運(yùn)行以下代碼
System.out.println (new Date ());
它給了我EDT時(shí)間。 我缺少什么配置。
參見stackoverflow.com/questions/3010035/
從控制臺(tái)中獲取的顯示中解釋日期對(duì)象時(shí)必須小心,因?yàn)樗鼈兪鞘褂眠\(yùn)行該程序的VM的默認(rèn)TimeZone格式化的(默認(rèn)情況下是從OS的時(shí)區(qū)繼承的)。
當(dāng)然,您可以根據(jù)Jesper的回答提供您自己的TimeZone。但是在這樣做的同時(shí),我強(qiáng)烈建議您使用IANA時(shí)區(qū)標(biāo)識(shí)符(例如America / New_York)而不是EST。之所以如此,是因?yàn)榫哂?#34;標(biāo)準(zhǔn)"的縮寫未考慮日光節(jié)約。
因此,如果僅在控制臺(tái)上打印日期對(duì)象,而沒有得到預(yù)期的結(jié)果,則很有可能將服務(wù)器時(shí)區(qū)設(shè)置為錯(cuò)誤的值,或者將OS設(shè)置為錯(cuò)誤的時(shí)區(qū)。
要更改JVM時(shí)區(qū),可以在啟動(dòng)時(shí)使用此參數(shù)
-Duser.timezone="America/New_York"
tl; dr
世界標(biāo)準(zhǔn)時(shí)間:
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
分區(qū):
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]
細(xì)節(jié)
Shailendra的答案是正確的。
另外,在Question中看到的Date類是麻煩的舊日期時(shí)間類的一部分,這些類現(xiàn)在已被遺留,完全被java.time類所取代。
java.util.Date的替換為java.time.Instant。 Instant類表示UTC時(shí)間軸上的時(shí)刻,其分辨率為納秒(最多十進(jìn)制的九(9)位數(shù)字)。
Instant::toString?始終使用UTC
調(diào)用舊類的Date::toString方法時(shí),其作者選擇的不幸行為是動(dòng)態(tài)應(yīng)用JVM的當(dāng)前默認(rèn)時(shí)區(qū)。這不會(huì)造成混亂。幸運(yùn)的是,現(xiàn)代類無需添加任何時(shí)區(qū)即可說出簡(jiǎn)單的事實(shí):Instant始終位于UTC中。
Instant.now().toString()
2018-03-16T00:57:34.233762Z
該字符串格式是標(biāo)準(zhǔn)的ISO 8601格式。最后的Z是Zulu的縮寫,表示UTC。
CEST Zone time
沒有名為CEST的時(shí)區(qū)。這樣的3-4個(gè)字母名稱是偽區(qū)域。它們不是標(biāo)準(zhǔn)化的。它們不是唯一的(!)。而是使用continent/region格式的正確時(shí)區(qū)。
ZoneId z = ZoneId.of("Europe/Paris" ) ;
您可以通過將ZoneId應(yīng)用于Instant以獲得ZoneDateTime,從UTC調(diào)整到這樣的時(shí)區(qū)。
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調(diào)整為另一個(gè)時(shí)區(qū)。注意,java.time使用不可變對(duì)象。因此,在調(diào)整過程中,我們會(huì)基于原始對(duì)象得到一個(gè)新的獨(dú)特對(duì)象,但又不會(huì)干擾原始對(duì)象。
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是三個(gè)單獨(dú)的對(duì)象,它們代表時(shí)間軸上的同一時(shí)刻,同一點(diǎn)。相同的時(shí)刻,不同的時(shí)鐘時(shí)間。
I have a Java Application running in my Ubuntu Server in USA and configure CEST Time Zone
僅供參考,一般來說,服務(wù)器默認(rèn)時(shí)區(qū)的最佳做法是UTC。
更重要的是,服務(wù)器操作系統(tǒng)和JVM的當(dāng)前默認(rèn)時(shí)區(qū)應(yīng)與Java應(yīng)用程序無關(guān)。
不要隱式依賴JVM的當(dāng)前默認(rèn)時(shí)區(qū),而應(yīng)始終明確指定所需/期望的時(shí)區(qū)。如上面的代碼所示,將可選的ZoneId參數(shù)傳遞給各種java.time方法。
(順便說一下,Locale的同上-始終指定所需/預(yù)期的語言環(huán)境,而不是隱式依賴于當(dāng)前默認(rèn)值。)
關(guān)于java.time
java.time框架內(nèi)置于Java 8及更高版本中。這些類取代了麻煩的舊版舊式日期時(shí)間類,例如java.util.Date,Calendar和SimpleDateFormat。
現(xiàn)在處于維護(hù)模式的Joda-Time項(xiàng)目建議遷移到j(luò)ava.time類。
要了解更多信息,請(qǐng)參見Oracle教程。并在Stack Overflow中搜索許多示例和說明。規(guī)格為JSR 310。
您可以直接與數(shù)據(jù)庫交換java.time對(duì)象。使用與JDBC 4.2或更高版本兼容的JDBC驅(qū)動(dòng)程序。不需要字符串,不需要java.sql.*類。
在哪里獲取java.time類?
Java SE 8,Java SE 9和更高版本
內(nèi)置的
標(biāo)準(zhǔn)Java API的一部分,具有捆綁的實(shí)現(xiàn)。
Java 9添加了一些次要功能和修復(fù)。
Java SE 6和Java SE 7
java.time的許多功能在ThreeTen-Backport中都被反向移植到Java 6和7。
安卓系統(tǒng)
更高版本的Android捆綁了java.time類的實(shí)現(xiàn)。
對(duì)于早期的Android(<26),ThreeTenABP項(xiàng)目改編了ThreeTen-Backport(如上所述)。請(qǐng)參閱如何使用ThreeTenABP…。
ThreeTen-Extra項(xiàng)目使用其他類擴(kuò)展了java.time。該項(xiàng)目為將來可能在java.time中添加內(nèi)容提供了一個(gè)試驗(yàn)場(chǎng)。您可能會(huì)在這里找到一些有用的類,例如Interval,YearWeek,YearQuarter等。
您說服務(wù)器配置為位于CEST時(shí)區(qū),但是根據(jù)Java,默認(rèn)時(shí)區(qū)為EDT。 Java從操作系統(tǒng)獲取默認(rèn)時(shí)區(qū),因此您的服務(wù)器可能未正確設(shè)置為CEST。
如果要在特定時(shí)區(qū)中打印日期,請(qǐng)使用DateFormat并在其上設(shè)置時(shí)區(qū):
DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss Z");
df.setTimeZone(TimeZone.getTimeZone("CET"));
System.out.println(df.format(new Date()));
注意:根據(jù)我的Java(Java 7u45),CEST不是有效的時(shí)區(qū)。您是說"英語四級(jí)考試"嗎? (CEST是CET的夏季變體,但是如果您使用CET,則Java將在適當(dāng)?shù)臅r(shí)候自動(dòng)在夏季顯示時(shí)間)。
總結(jié)
以上是生活随笔為你收集整理的java 时区 不正确_Java中的时区不匹配的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 小企业财务软件哪个最好用,该如何选择?
- 下一篇: java日期 13,如何将此格式的日期(