簡體   English   中英

SimpleDateFormat.parse生成不一致的結果

[英]SimpleDateFormat.parse generating inconsistent results

我正在使用SimpleDateFormat將字符串解析為DateTime,如下面的代碼所示。

val formatSrc = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'")
formatSrc.setLenient(false)
val temp = formatSrc.parse("2017-02-04T09:55:42.000Z")
print(temp)

結果應為Sat Feb 04 09:55:42 UTC 2017 ,但是我得到的結果不一致,例如,它可能低於Tue Feb 04 00:00:04 UTC 2200Wed Feb 04 09:55:42 UTC 2201Wed Feb 04 09:55:42 UTC 2201 ,或其他一些東西。 順便說一句,我將Scala與Spark結合使用來處理一些文本數據。 知道為什么嗎?

這個問題可能是 (盡管不能肯定)一個並發問題: SimpleDateFormat從其Javadoc來看不是線程安全的:

日期格式不同步。 建議為每個線程創建單獨的格式實例。 如果多個線程同時訪問一種格式,則必須在外部進行同步。

Spark顯然使用了多個線程(通常來說,每個分區一個)-如果這些線程共享相同的SimpleDateFormat實例,則可以解釋您所看到的行為。

要解決此問題,請使用其他線程安全格式化程序,或者為每個記錄/分區創建一個單獨的格式化程序。

在格式化程序上將時區設置為UTC(GMT),否則您轉義的尾隨“ Z”(因此錯誤地解釋為文字)將無法理解為UTC + 00:

formatSrc.setTimeZone(TimeZone.getTimeZone("GMT"));

注意:如果您想將解析結果與方法print(temp)進行比較,那么我擔心您只是隱式地使用Date -method toString() ,它使用完全不同的格式(在默認時區中)。

我認為Tzach的回答很有道理。 我沒有為每個線程創建一個單獨的實例。 因此這應該是多線程問題,因為Spark顯然是多線程的。 我將其替換為線程安全的Joda DateTimeFormat。 然后問題解決了。 http://joda-time.sourceforge.net/apidocs/org/joda/time/format/DateTimeFormat.html

您的日期時間格式恰好適合ISO 8601即時。 現代的Java日期和時間API與ISO 8601配合得很好。因此,我建議您使用它。

抱歉,我無法編寫Scala代碼,因此您必須從Java進行翻譯:

    Instant temp = Instant.parse("2017-02-04T09:55:42.000Z");

好處:

  • 您已經跳過了已經過時的SimpleDateFormatDate類,並開始使用它們的現代替代方法。
  • 這是一行而不是三行,可以更清楚地表達您的意圖。
  • 解析是線程安全的,因此,如果Tzach Zohar猜對了,便可以解決您的問題。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM