[英]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 2200
或Wed Feb 04 09:55:42 UTC 2201
日Wed 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");
好處:
SimpleDateFormat
和Date
類,並開始使用它們的現代替代方法。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.