python - 根据列获取 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 |
+--------------------------+-----------------------------------+
解决方案
而是使用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 平台只能识别其中之一他们。
推荐阅读
- php - 将参数传递给字符串
- shell - neo4j 无法在来自 cypher shell 的 5000 毫秒消息中建立连接
- c# - 删除损坏的 user.config 而不是 System.ConfigurationErrorException
- python - 如何将 QComboBox 中的文本存储在全局变量中
- linux - 在 Linux 上使用 .net 核心更改 IP 地址
- c - 如何检测同时按下按钮
- javascript - Json 对象到网络图的数组
- jquery - Rails + JQuery 侧边栏下拉菜单立即关闭
- php - 如何在mysql中关系数据的每个父记录上选择n个记录子记录
- linux - 匹配 if 条件中的字符串