首页 > 解决方案 > 使用 Spark SQL 将日期时间四舍五入到最近的午夜

问题描述

我有一个带有 datetime 列的 Spark 数据框,格式为yyyy-MM-dd HH:mm:SS

我的数据框如下所示:

日期时间列 输出列
2021-01-29 21:30:00 2021-01-30 00:00:00
2021-01-30 05:30:00 2021-01-30 00:00:00
2021-01-01 23:25:00 2021-01-02 00:00:00
2021-01-02 08:59:59 2021-01-02 00:00:00

如何使用 Spark SQLoutput_column从列中获取列?datetime_column

注意:我的数据 ( datetime_column) 将始终存在于晚上 9 点到上午 9 点之间,因此查找最近的午夜很简单。

我正在使用 PySpark 2.4.6

标签: apache-sparkpysparkapache-spark-sql

解决方案


这是一个通过计算第二个值中最近的日期来执行“四舍五入”的技巧(即round((timestamp // 86400) * 86400)。这与我将数字四舍五入到最接近的 1000 所做的事情相同round(number//1000)*1000:)

(df.select(f.from_unixtime(f.round(
    f.unix_timestamp('datetime_column') / 
    f.lit(86400)) * f.lit(86400)).alias('output_column') )).show()

输出:

+-------------------+
|      output_column|
+-------------------+
|2021-01-30 02:00:00|
|2021-01-30 02:00:00|
|2021-01-02 02:00:00|
|2021-01-02 02:00:00|
+-------------------+

请注意,上面的结果显示在我的时区中,其偏移量为 +02:00(from_unixtime转换为当前时区的时间戳)。如果您需要准确的结果,请务必UTC在运行代码之前在 Spark 配置中设置为系统时区(函数文档中提到了这一点):

spark.conf.set("spark.sql.session.timeZone", "UTC")
(df.select(f.from_unixtime(f.round(
    f.unix_timestamp('datetime_column') / 
    f.lit(86400)) * f.lit(86400)).alias('output_column'))).show()
spark.conf.unset("spark.sql.session.timeZone") # unset it

这会产生您确切的预期输出

+-------------------+
|      output_column|
+-------------------+
|2021-01-30 00:00:00|
|2021-01-30 00:00:00|
|2021-01-02 00:00:00|
|2021-01-02 00:00:00|
+-------------------+

推荐阅读