使用 PySpark 将 unix 时间转换为日期时间

Converting unix time to datetime with PySpark

我有 PySpark 数据框,其中包含“日期”列,它代表浮点类型的 unix 时间(如 1.63144269E9)。当我将这个时间转换为 "yyyy-MM-dd HH:mm:ss.SSS" 日期时间格式时,PySpark 给了我不正确的值。

例如,将 unix 时间 1631442679.384516 转换为日期时间 PySpark 得到 "2021-09-12 12:31:28.000" .小时数、秒数、毫秒数错误。

我尝试了不同的 PySpark 函数,它们没有给出正确的值。

例如:

j = df.withColumn('epoch', f.from_unixtime(f.col("date"), "yyyy-MM-dd HH:mm:ss.SSS"))
j.select("epoch").show(5, False)
+-----------------------+
|epoch                  |
+-----------------------+
|2021-09-12 12:31:28.000|
|2021-09-12 12:31:28.000|
|2021-09-12 12:31:28.000|
|2021-09-12 12:31:28.000|
|2021-09-12 12:31:28.000|
+-----------------------+ 

当我使用“日期”为 StringType 的方案创建数据框时,结果如下所示。

+-----------------------+
|epoch                  |
+-----------------------+
|2021-09-12 12:31:19.000|
|2021-09-12 12:31:19.000|
|2021-09-12 12:31:19.000|
|2021-09-12 12:31:19.000|
|2021-09-12 12:31:20.000|
+-----------------------+

现在秒是正确的,但小时和毫秒仍然是错误的。

我做错了什么?

更新 1.0

我在数据帧方案中将 FloatType 切换为 DecimalType 并使用了下一个代码:

j = df.withColumn('epoch', f.col('date').cast("timestamp"))
j.select("epoch").show(5, False)

结果:

+-----------------------+
|epoch                  |
+-----------------------+
|2021-09-12 12:31:19.385|
|2021-09-12 12:31:19.435|
|2021-09-12 12:31:19.547|
|2021-09-12 12:31:19.571|
|2021-09-12 12:31:20.012|
+-----------------------+

小时数仍然错误。我可以尝试使用 from_utc_timestamp(j.epoch, "GMT-3") 并且时间是正确的,但是这个函数在性能上太长了。我想 df.withColumn('epoch', f.col('date').cast("timestamp")) 使用我 PC 的时区,但我不知道如何以更好的方式修复它。

更新 2.0

我用一个简单的决定减去两个小时,效果很好。

j = df.withColumn('epoch', (f.col('date')- 7200).cast("timestamp"))
j.select("epoch").show(5, False)

结果:

+-----------------------+
|epoch                  |
+-----------------------+
|2021-09-12 10:31:19.385|
|2021-09-12 10:31:19.435|
|2021-09-12 10:31:19.547|
|2021-09-12 10:31:19.571|
|2021-09-12 10:31:20.012|
+-----------------------+

根据 from_unixtime and default configurationsspark.sql.session.timeZone 的默认值是 Spark 本地时间,这就是为什么您在这里看到一些不同的时间。正确的处理方法是按照您的期望更改 Spark 时区。

spark.conf.set("spark.sql.session.timeZone", "America/Los_Angeles")