簡體   English   中英

為什么在 Spark 中傳遞格式錯誤的時區字符串時 from_utc_timstamp 不拋出錯誤?

[英]Why doesn't from_utc_timstamp throw an error when passed a malformed timezone string in Spark?

在 spark 2.4.3 中調用 from_utc_timestamp function 時,如果我傳入格式錯誤的時區字符串,則不會引發錯誤。 相反,它只是默認為 UTC,這與我的預期背道而馳,而且似乎也可能導致 go 的錯誤被忽視。 這是故意的,還是 Spark 中的錯誤?

請參見下面的示例:

scala> val df =  Seq(("2020-01-01 00:00:00")).toDF("date")
df: org.apache.spark.sql.DataFrame = [date: string]

scala> df.show()

// Not a real timezone obviously. Just gets treated like UTC.
scala> df.withColumn("est", from_utc_timestamp(col("date"), "not_a_real_timezone")).show()
+-------------------+-------------------+
|               date|                est|
+-------------------+-------------------+
|2020-01-01 00:00:00|2020-01-01 00:00:00|
+-------------------+-------------------+

// Typo in EST5PDT, so still not a real timezone. Also defaults to UTC, which makes it
// very easy to miss this mistake.
scala> df.withColumn("est", from_utc_timestamp(col("date"), "EST5PDT")).show()
+-------------------+-------------------+
|               date|                est|
+-------------------+-------------------+
|2020-01-01 00:00:00|2020-01-01 00:00:00|
+-------------------+-------------------+

// EST8EDT is a real timezone, so this works as expected.
scala> df.withColumn("est", from_utc_timestamp(col("date"), "EST5EDT")).show()
+-------------------+-------------------+
|               date|                est|
+-------------------+-------------------+
|2020-01-01 00:00:00|2019-12-31 19:00:00|
+-------------------+-------------------+

from_utc_timestamp使用來自org.apache.spark.sql.catalyst.utilDateTimeUtils 要獲取時區,他們使用getTimeZone方法。 這種方法通常不會引發問題。

  • 這可能是 JVM 的事情,其中 JVM 試圖避免依賴系統的默認語言環境、字符集和時區
  • 這可能是在 Jira 中登錄的 Spark 問題

但是看看其他人的代碼,他們確實有一個首先檢查的設置:

import java.util.TimeZone

...

if (!TimeZone.getAvailableIDs().contains(tz)) {
  throw new IllegalStateException(s"The setting '$tz' is not recognized as known time zone")
}

EDIT1:剛剛發現它是一個“功能”。 它在 3.0.0 的遷移指南中

在 Spark 版本 2.4 和更早版本中,無效的時區 ID 會被忽略並替換為 GMT 時區,例如,在 from_utc_timestamp function 中。 從 Spark 3.0 開始,此類時區 ID 被拒絕,並且 Spark 拋出 java.time.DateTimeException。

https://spark.apache.org/docs/3.0.0-preview/sql-migration-guide.html

from_utc_timestamp調用DateTimeUtils.fromUTCTime

def fromUTCTime(time: SQLTimestamp, timeZone: String): SQLTimestamp = {
  convertTz(time, TimeZoneGMT, getTimeZone(timeZone))
}

要將時區字符串轉換為時object function 調用getTimeZone ,這里調用 JDK 的TimeZone.getTimeZone將時區字符串轉換為實際時區 ZA8CFDE6331BD49EB216ZC96F966 該方法的 Javadoc 聲明該方法返回

指定的時區,如果給定的 ID 無法理解,則為 GMT 時區

在您的EST5PDT情況下,找不到該字符串的時區,因此返回值為GMT 結果,SQLTimestamp 從 GMT 轉換為 GMT,這意味着它保持不變。

暫無
暫無

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

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