Spark 3.2如何获取带冒号时区偏移的本地时间戳
解决Spark 3.2生成带冒号时区偏移的时间戳问题
Spark 3.2版本的date_format函数中,Z模式返回的是不带冒号的时区偏移(如+0930),而支持带冒号偏移的XXX模式是Spark 3.3及以上才引入的。要生成类似2023-08-28T03:51:46.222+09:30的格式,需要通过拆分拼接的方式实现,以下是两种可行方案:
方案一:使用字符串函数拼接(无需UDF)
直接用Spark内置字符串函数拆分时区偏移并插入冒号,避免自定义UDF的性能开销:
from pyspark.sql import functions as F df.select( F.concat( # 获取到毫秒的日期时间部分 F.date_format( F.from_utc_timestamp(F.current_timestamp(), 'Australia/Adelaide'), "yyyy-MM-dd'T'HH:mm:ss.SSS" ), # 拆分并格式化时区偏移:从+0930转为+09:30 F.concat( F.substring( F.date_format(F.from_utc_timestamp(F.current_timestamp(), 'Australia/Adelaide'), "Z"), 1, 3 ), F.lit(":"), F.substring( F.date_format(F.from_utc_timestamp(F.current_timestamp(), 'Australia/Adelaide'), "Z"), 4, 2 ) ) ).alias("formatted_timestamp") ).show(1, truncate=0)
方案二:自定义UDF处理时区偏移
如果需要复用偏移格式化逻辑,可以封装成UDF:
from pyspark.sql import functions as F from pyspark.sql.types import StringType # 给时区偏移添加冒号的UDF def format_timezone_offset(offset): # 偏移格式为±HHMM,长度5位(如+0930) if len(offset) == 5: return f"{offset[:3]}:{offset[3:]}" return offset format_offset_udf = F.udf(format_timezone_offset, StringType()) df.select( F.concat( F.date_format( F.from_utc_timestamp(F.current_timestamp(), 'Australia/Adelaide'), "yyyy-MM-dd'T'HH:mm:ss.SSS" ), format_offset_udf( F.date_format(F.from_utc_timestamp(F.current_timestamp(), 'Australia/Adelaide'), "Z") ) ).alias("formatted_timestamp") ).show(1, truncate=0)
补充说明
- 先通过
from_utc_timestamp将当前UTC时间转换为目标时区(如Australia/Adelaide)的时间; - 拆分出日期时间部分和时区偏移部分,对偏移部分插入冒号后拼接,最终得到符合要求的格式;
- 若之前代码返回
+0000,需检查Spark会话的时区配置,确保current_timestamp()返回的是UTC时间,或直接用F.current_timestamp().cast("timestamp")明确类型。
内容的提问来源于stack exchange,提问作者ZygD
相关产品推荐
相关产品推荐

