从 Spark 2.0 到 3.0 的字符串到日期迁移导致无法识别 DateTimeFormatter 中的“EEE MMM dd HH:mm:ss zzz yyyy”模式

lak*_*euk 7 apache-spark apache-spark-sql pyspark

我有一个来自源的日期字符串,格式为“Fri May 24 00:00:00 BST 2019”,我将使用类似我的示例的代码将其转换为日期并存储为“2019-05-24”对我来说在 spark 2.0 下

from pyspark.sql.functions import to_date, unix_timestamp, from_unixtime
df = spark.createDataFrame([("Fri May 24 00:00:00 BST 2019",)], ['date_str'])
df2 = df.select('date_str', to_date(from_unixtime(unix_timestamp('date_str', 'EEE MMM dd HH:mm:ss zzz yyyy'))).alias('date'))
df2.show(1, False)
Run Code Online (Sandbox Code Playgroud)

在我的沙箱环境中,我已经更新到 spark 3.0,现在上面的代码出现以下错误,是否有在 3.0 中执行此操作的新方法将我的字符串转换为日期

: org.apache.spark.SparkUpgradeException: 由于 Spark 3.0 的升级,您可能会得到不同的结果:无法识别 DateTimeFormatter 中的“EEE MMM dd HH:mm:ss zzz yyyy”模式。

  1. 您可以将 spark.sql.legacy.timeParserPolicy 设置为 LEGACY 以恢复 Spark 3.0 之前的行为。
  2. 您可以使用https://spark.apache.org/docs/latest/sql-ref-datetime-pattern.html 中的指南形成有效的日期时间模式

小智 10

如果要在较新版本的 spark(>3) 中使用旧格式,则需要设置spark.conf.set("spark.sql.legacy.timeParserPolicy","LEGACY")spark.sql("set spark.sql.legacy.timeParserPolicy=LEGACY"),这将解决问题。


lak*_*euk 5

感谢您的回复和极好的建议,目前我将使用 LEGACY 设置。我有一个 Spark 3.0 的解决方法,通过子串化 EEE 元素,但我注意到 BST 时区如何转换错误地偏移 10 小时,而在 LEGACY 下它正确地保持与我当前在 BST 时区相同的错误。我可以对此做点什么,但要等到秋天的时钟改变才能确认。

spark.sql("set spark.sql.legacy.timeParserPolicy=LEGACY")
df = spark.createDataFrame([('Fri May 24 00:00:00 BST 2019',)], ['mydate'])
df = df.select('mydate',
                to_timestamp(df.mydate.substr(5, 28), 'MMM dd HH:mm:ss zzz yyyy').alias('datetime'),
                to_timestamp(df.mydate, 'EEE MMM dd HH:mm:ss zzz yyyy').alias('LEGACYdatetime')
               ).show(1, False)

df = spark.createDataFrame([('Fri May 24 00:00:00 GMT 2019',)], ['mydate'])
df = df.select('mydate', 
                to_timestamp(df.mydate.substr(5, 28), 'MMM dd HH:mm:ss zzz yyyy').alias('datetime'),
                to_timestamp(df.mydate, 'EEE MMM dd HH:mm:ss zzz yyyy').alias('LEGACYdatetime')
               ).show(1, False)

spark.sql("set spark.sql.legacy.timeParserPolicy=CORRECTED")
df = spark.createDataFrame([('Fri May 24 00:00:00 BST 2019',)], ['mydate'])
df = df.select('mydate', 
                to_timestamp(df.mydate.substr(5, 28), 'MMM dd HH:mm:ss zzz yyyy').alias('datetime')          
               ).show(1, False)

df = spark.createDataFrame([('Fri May 24 00:00:00 GMT 2019',)], ['mydate'])
df = df.select('mydate', 
                to_timestamp(df.mydate.substr(5, 28), 'MMM dd HH:mm:ss zzz yyyy').alias('datetime')           
               ).show(1, False)
Run Code Online (Sandbox Code Playgroud)
+----------------------------+-------------------+-------------------+
|mydate                      |datetime           |LEGACYdatetime     |
+----------------------------+-------------------+-------------------+
|Fri May 24 00:00:00 BST 2019|2019-05-24 00:00:00|2019-05-24 00:00:00|
+----------------------------+-------------------+-------------------+

+----------------------------+-------------------+-------------------+
|mydate                      |datetime           |LEGACYdatetime     |
+----------------------------+-------------------+-------------------+
|Fri May 24 00:00:00 GMT 2019|2019-05-24 01:00:00|2019-05-24 01:00:00|
+----------------------------+-------------------+-------------------+

+----------------------------+-------------------+
|mydate                      |datetime           |
+----------------------------+-------------------+
|Fri May 24 00:00:00 BST 2019|2019-05-23 14:00:00|
+----------------------------+-------------------+

+----------------------------+-------------------+
|mydate                      |datetime           |
+----------------------------+-------------------+
|Fri May 24 00:00:00 GMT 2019|2019-05-24 01:00:00|
+----------------------------+-------------------+
Run Code Online (Sandbox Code Playgroud)