Scala:使用 spark 3.1.2 解析时间戳
Scala: Parse timestamp using spark 3.1.2
我有一个 Excel-reader,我将结果放在 sparks 数据帧中。我在解析时间戳时遇到问题。
我有像 Wed Dec 08 10:49:59 CET 2021
这样的字符串形式的时间戳。我使用的是 spark-sql 版本 2.4.5
并且一切正常,直到我最近更新到版本 3.1.2
.
请在下面找到一些最少的代码。
import org.apache.spark.sql.SparkSession
import org.apache.spark.sql.functions.{col, to_timestamp}
val ts: String = "Wed Dec 08 20:49:59 CET 2021"
val oldfmt: String = "E MMM dd HH:mm:ss z yyyy"
val ttdf = Seq(ts)
.toDF("theTimestampColumn")
.withColumn("parsedTime", to_timestamp(col("theTimestampColumn"), fmt = oldfmt))
ttdf.show()
运行 spark 版本 2.4.5
的代码按预期工作并产生以下输出:
+--------------------+-------------------+
| theTimestampColumn| parsedTime|
+--------------------+-------------------+
|Wed Dec 08 20:49:...|2021-12-08 20:49:59|
+--------------------+-------------------+
现在,仅使用 spark 版本 3.1.2
执行相同的代码会导致以下错误:
Exception in thread "main" org.apache.spark.SparkUpgradeException:
You may get a different result due to the upgrading of Spark 3.0:
Fail to recognize 'E MMM dd HH:mm:ss z yyyy' pattern in the DateTimeFormatter.
1) You can set spark.sql.legacy.timeParserPolicy to LEGACY to restore the behavior before Spark 3.0.
2) You can form a valid datetime pattern with the guide from https://spark.apache.org/docs/latest/sql-ref-datetime-pattern.html
(可点击 link: https://spark.apache.org/docs/latest/sql-ref-datetime-pattern.html)
这个网站对我没有进一步的帮助。我在我的格式字符串中没有发现任何错误。
符号 E
将 day-of-week
表示为类似于 Tue; Tuesday
的文本。
符号 M
代表 month-of-year
就像 7; 07; Jul; July
。符号 H,m,s,y
分别表示小时、分钟、秒或年。符号 z
表示 time-zone name
类似于 Pacific Standard Time; PST
。
我在这里错过了一些明显的东西吗?
任何帮助将不胜感激。提前谢谢你。
您只能将 E
用于日期时间格式,而不能用于解析,如 datetime pattern documentation:
中所述
Symbols of ‘E’, ‘F’, ‘q’ and ‘Q’ can only be used for datetime formatting, e.g. date_format. They are not allowed used for datetime parsing, e.g. to_timestamp.
如果您想应用 Spark <3.0 版本的行为,您可以将 spark.sql.legacy.timeParserPolicy
选项设置为 LEGACY
:
sparkSession.conf.set("spark.sql.legacy.timeParserPolicy", "LEGACY")
如果你不想改变spark配置,你可以用substr
SQL函数去掉代表天的字符:
import org.apache.spark.sql.functions.{col, to_timestamp, expr}
val ts: String = "Wed Dec 08 20:49:59 CET 2021"
val fmt: String = "MMM dd HH:mm:ss z yyyy"
val ttdf = Seq(ts)
.toDF("theTimestampColumn")
.withColumn("preparedTimestamp", expr("substr(theTimestampColumn, 5, length(theTimestampColumn))"))
.withColumn("parsedTime", to_timestamp(col("preparedTimestamp"), fmt = fmt))
.drop("preparedTimestamp")
我有一个 Excel-reader,我将结果放在 sparks 数据帧中。我在解析时间戳时遇到问题。
我有像 Wed Dec 08 10:49:59 CET 2021
这样的字符串形式的时间戳。我使用的是 spark-sql 版本 2.4.5
并且一切正常,直到我最近更新到版本 3.1.2
.
请在下面找到一些最少的代码。
import org.apache.spark.sql.SparkSession
import org.apache.spark.sql.functions.{col, to_timestamp}
val ts: String = "Wed Dec 08 20:49:59 CET 2021"
val oldfmt: String = "E MMM dd HH:mm:ss z yyyy"
val ttdf = Seq(ts)
.toDF("theTimestampColumn")
.withColumn("parsedTime", to_timestamp(col("theTimestampColumn"), fmt = oldfmt))
ttdf.show()
运行 spark 版本 2.4.5
的代码按预期工作并产生以下输出:
+--------------------+-------------------+
| theTimestampColumn| parsedTime|
+--------------------+-------------------+
|Wed Dec 08 20:49:...|2021-12-08 20:49:59|
+--------------------+-------------------+
现在,仅使用 spark 版本 3.1.2
执行相同的代码会导致以下错误:
Exception in thread "main" org.apache.spark.SparkUpgradeException:
You may get a different result due to the upgrading of Spark 3.0:
Fail to recognize 'E MMM dd HH:mm:ss z yyyy' pattern in the DateTimeFormatter.
1) You can set spark.sql.legacy.timeParserPolicy to LEGACY to restore the behavior before Spark 3.0.
2) You can form a valid datetime pattern with the guide from https://spark.apache.org/docs/latest/sql-ref-datetime-pattern.html
(可点击 link: https://spark.apache.org/docs/latest/sql-ref-datetime-pattern.html)
这个网站对我没有进一步的帮助。我在我的格式字符串中没有发现任何错误。
符号 E
将 day-of-week
表示为类似于 Tue; Tuesday
的文本。
符号 M
代表 month-of-year
就像 7; 07; Jul; July
。符号 H,m,s,y
分别表示小时、分钟、秒或年。符号 z
表示 time-zone name
类似于 Pacific Standard Time; PST
。
我在这里错过了一些明显的东西吗?
任何帮助将不胜感激。提前谢谢你。
您只能将 E
用于日期时间格式,而不能用于解析,如 datetime pattern documentation:
Symbols of ‘E’, ‘F’, ‘q’ and ‘Q’ can only be used for datetime formatting, e.g. date_format. They are not allowed used for datetime parsing, e.g. to_timestamp.
如果您想应用 Spark <3.0 版本的行为,您可以将 spark.sql.legacy.timeParserPolicy
选项设置为 LEGACY
:
sparkSession.conf.set("spark.sql.legacy.timeParserPolicy", "LEGACY")
如果你不想改变spark配置,你可以用substr
SQL函数去掉代表天的字符:
import org.apache.spark.sql.functions.{col, to_timestamp, expr}
val ts: String = "Wed Dec 08 20:49:59 CET 2021"
val fmt: String = "MMM dd HH:mm:ss z yyyy"
val ttdf = Seq(ts)
.toDF("theTimestampColumn")
.withColumn("preparedTimestamp", expr("substr(theTimestampColumn, 5, length(theTimestampColumn))"))
.withColumn("parsedTime", to_timestamp(col("preparedTimestamp"), fmt = fmt))
.drop("preparedTimestamp")