PySpark如何将带时区信息的时间戳转换为指定时区的对应时间
问题核心原因
from_utc_timestamp设计上仅接受不带时区信息的UTC时间戳作为输入,若传入自带时区标识的timestamp/时间字符串,Spark会先按自带时区将其转换为会话本地时区对应的时间,再执行转换逻辑,最终导致结果偏移。
可行解决方案
方案1:使用Spark 3.0+原生convert_timezone函数(推荐)
该函数原生支持跨时区转换,无需修改会话配置,也无需使用UDF,直接指定源时区、目标时区和时间列即可:
F.convert_timezone("UTC", "America/New_York", F.col("ts"))
输入为带Z的UTC时间字符串或已解析的timestamp类型都可直接使用,输出结果与预期一致:datetime.datetime(2012, 11, 20, 12, 39, 37)。
方案2:兼容低版本Spark的处理方式
如果使用的是Spark 3.0以下版本,可先将输入时间转换为不带时区信息的UTC naive时间戳,再调用from_utc_timestamp:
输入为字符串类型的带Z时间
# 先按字符串匹配解析为不带时区的UTC naive时间戳,把Z当成普通字符忽略 naive_utc_ts = F.to_timestamp(F.col("ts"), "yyyy-MM-dd'T'HH:mm:ss'Z'") # 转换为纽约时区 result = F.from_utc_timestamp(naive_utc_ts, "America/New_York")
输入已为Timestamp类型
# 先格式化为无时区的UTC时间字符串,再解析为naive时间戳 naive_utc_ts = F.to_timestamp(F.date_format(F.col("ts"), "yyyy-MM-dd HH:mm:ss"), "yyyy-MM-dd HH:mm:ss") result = F.from_utc_timestamp(naive_utc_ts, "America/New_York")
内容的提问来源于stack exchange,提问作者LetsPlayYahtzee
相关产品推荐
相关产品推荐

