首页 > 解决方案 > 根据列获取 pyspark 中的当地时间

问题描述

在 pyspark 中,可以通过将时间戳和时区传递给函数来从 UTC 时间获取本地时间 from_utc_timestamp

>>> df = spark.createDataFrame([('1997-02-28 10:30:00',)], ['t'])
>>> df.select(from_utc_timestamp(df.t, "PST").alias('t')).collect()
[Row(t=datetime.datetime(1997, 2, 28, 2, 30))]

此处的时区以字符串文字 ("PST") 的形式提供。如果要具有以下数据结构:

+--------------------------+---------+
| utc_time                 |timezone |
+--------------------------+---------+
|  2018-08-03T23:27:30.000Z|  PST    |
|  2018-08-03T23:27:30.000Z|  GMT    |
|  2018-08-03T23:27:30.000Z|  SGT    |
+--------------------------+---------+

如何实现以下新列(最好没有 UDF)?

+--------------------------+-----------------------------------+
| utc_time                 |timezone | local_time              |
+--------------------------+-----------------------------------+
|  2018-08-03T23:27:30.000Z|  PST    | 2018-08-03T15:27:30.000 |
|  2018-08-03T23:27:30.000Z|  GMT    | 2018-08-04T00:27:30.000 |
|  2018-08-03T23:27:30.000Z|  SGT    | 2018-08-04T07:27:30.000 |
+--------------------------+-----------------------------------+

标签: pythondatetimeapache-sparkpysparkapache-spark-sql

解决方案


而是使用pyspark.sql.functions.expr()dataframe API,这可以通过以下方式实现:

import pyspark.sql.functions as F

df = df.select(
    '*',
    F.expr('from_utc_timestamp(utc_time, timezone)').alias("timestamp_local")
)

但是,不推荐使用 3 个字母的时区。根据Java 文档

为了与 JDK 1.1.x 兼容,还支持一些其他的三字母时区 ID(例如“PST”、“CTT”、“AST”)。但是,不推荐使用它们,因为相同的缩写通常用于多个时区(例如,“CST”可能是美国“中部标准时间”和“中国标准时间”),Java 平台只能识别其中之一他们。


推荐阅读