Scala 为什么';在Spark中传递格式错误的时区字符串时,t from_utc_timstamp是否会引发错误?

Scala 为什么';在Spark中传递格式错误的时区字符串时,t from_utc_timstamp是否会引发错误?,scala,apache-spark,Scala,Apache Spark,在spark 2.4.3中调用from_utc_timestamp函数时,如果传入格式错误的时区字符串,则不会引发错误。相反,它只是默认为UTC,这与我的预期背道而驰,而且似乎还可能导致错误被忽略。这是故意的,还是Spark中的bug 见下例: scala> val df = Seq(("2020-01-01 00:00:00")).toDF("date") df: org.apache.spark.sql.DataFrame = [date: string] scala> df

在spark 2.4.3中调用from_utc_timestamp函数时,如果传入格式错误的时区字符串,则不会引发错误。相反,它只是默认为UTC,这与我的预期背道而驰,而且似乎还可能导致错误被忽略。这是故意的,还是Spark中的bug

见下例:

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|
+-------------------+-------------------+


来自utc时间戳的
使用来自org.apache.spark.sql.catalyst.util的
DateTimeUtils
。为了获得时区,他们使用
getTimeZone
方法。这种方法通常不会引发问题

  • 这可能是JVM的问题,JVM试图避免依赖于系统的默认语言环境、字符集和时区
  • 这可能是Jira中记录的火花问题
但看看其他人的代码,他们确实有一个先检查的设置:

import java.util.TimeZone
...
如果(!TimeZone.getAvailableIDs().包含(tz)){
抛出新的IllegalStateException(设置“$tz”未被识别为已知时区)
}
编辑1: 刚发现这是一个“特征”。它在3.0.0的迁移指南中

在Spark版本2.4和更早版本中,无效的时区ID将被静默忽略并替换为GMT时区,例如,在from_utc_timestamp函数中。自Spark 3.0以来,此类时区ID被拒绝,Spark抛出java.time.DateTimeException


来自utc时间戳的呼叫

def fromUTCTime(时间:SQLTimestamp,时区:字符串):SQLTimestamp={
convertTz(时间、时区、getTimeZone(时区))
}
要将时区字符串转换为对象,函数调用,这里调用JDK将时区字符串转换为实际的时区对象。该方法的Javadoc声明该方法返回

指定的时区,如果无法理解给定ID,则为GMT时区

在您的示例中,
EST5PDT
找不到此字符串的时区,因此返回值为
GMT
。结果,SQLTimestamp从GMT转换为GMT,这意味着它保持不变