You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PySpark to_timestamp解析可变长度毫秒如何正确归一化为SSS格式

问题根因

Spark 3.2.1 内置to_timestamp使用SimpleDateFormat做时间格式解析时,固定写死SSS匹配毫秒会按左对齐逻辑处理长度不足3位的毫秒值:直接读取小数点后连续的数字,不足3位时在左侧补0凑够3位,完全不符合毫秒作为时间小数位需要右侧补0的逻辑,因此出现解析错位。另外原格式串里小时位用hh是12小时制,遇到12点之后的时间会直接解析错误,需要替换为24小时制的HH。

解决方案

不要直接把原始字符串传入固定格式的to_timestamp,先做字符串预处理,把毫秒位统一右补0到3位,再做时间解析:

  • 用正则拆分出时间字符串里「小数点前的前缀部分」「小数点后的毫秒数字部分」「末尾的Z时区标识」
  • 对提取到的毫秒数字段用rpad函数右侧补0,统一填充到3位长度
  • 拼接成标准的3位毫秒UTC时间字符串,再传入to_timestamp按固定格式解析

可直接复用的代码如下:

import pyspark.sql.functions as F

test = spark.createDataFrame([
    (1,'2022-06-16T07:01:25.346Z'),
    (2,'2022-06-16T06:54:21.51Z'),
    (3,'2022-06-16T06:54:21.5Z')
],['no','timing1'])

# 预处理:统一补全毫秒到3位
test = test.withColumn(
    "time_prefix",
    F.regexp_extract(F.col("timing1"), r"^(.*\.)", 1)
).withColumn(
    "millisecond",
    F.rpad(F.regexp_extract(F.col("timing1"), r"\.(\d+)Z$", 1), 3, "0")
).withColumn(
    "standard_time_str",
    F.concat(F.col("time_prefix"), F.col("millisecond"), F.lit("Z"))
)

# 按标准格式解析,注意小时用24小时制HH
parse_format = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"
test = test.withColumn("correct_time", F.to_timestamp(F.col("standard_time_str"), format=parse_format))

# 输出验证结果
test.select("timing1", "correct_time").show(truncate=False)
解析结果

运行后输出完全符合预期:

+------------------------+-----------------------+
|timing1                 |correct_time           |
+------------------------+-----------------------+
|2022-06-16T07:01:25.346Z|2022-06-16 07:01:25.346|
|2022-06-16T06:54:21.51Z |2022-06-16 06:54:21.51 |
|2022-06-16T06:54:21.5Z  |2022-06-16 06:54:21.5  |
+------------------------+-----------------------+

内容的提问来源于stack exchange,提问作者lil-wolf

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 20:27:26