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

PySpark如何将时间戳字符串转换为天.时:分:秒格式输出

PySpark 时间戳转天.时:分:秒.毫秒格式实现

原代码失效原因

  • 原逻辑先将时间格式化为字符串再强转timestamp类型,字符串格式和timestamp默认解析规则不匹配,导致date_sub入参为null,最终计算结果为空
  • 原代码用d格式化符取的是自然月内的日期数,而目标格式的天是从UTC时间1970-01-01 00:00:00开始计算的间隔天数,取自然日的逻辑本身不符合需求
  • date_sub第二个参数传-1实际是日期加1天,和“减1天”的预期操作相反

正确转换代码

核心思路:先解析带时区的输入时间戳为标准时间类型,计算其与Unix纪元起点的总时间差,再拆分出天、小时、分钟、秒、毫秒字段,最终拼接为目标格式。

from pyspark.sql import functions as F

# 构造测试数据集
df = spark.createDataFrame(
    [['1970-01-13T22:05:38.391+0000', '12.22:05:38.3910000']],
    ["ts", "expectedValue"]
)

# 执行转换
df = df.withColumn(
    "ts_parsed",
    F.to_timestamp("ts", "yyyy-MM-dd'T'HH:mm:ss.SSSZ")  # 解析带时区的输入时间戳
).withColumn(
    "epoch_start",
    F.lit("1970-01-01 00:00:00").cast("timestamp")  # 定义Unix纪元起点(UTC)
).withColumn(
    "total_seconds",
    F.col("ts_parsed").cast("double") - F.col("epoch_start").cast("double")  # 计算与纪元起点的秒级差
).withColumn(
    "day_part",
    F.floor(F.col("total_seconds") / 86400).cast("string")  # 拆分天部分:1天=86400秒
).withColumn(
    "remain_after_day",
    F.col("total_seconds") % 86400
).withColumn(
    "hour_part",
    F.lpad(F.floor(F.col("remain_after_day") / 3600).cast("string"), 2, "0")  # 拆分小时部分:1小时=3600秒,不足2位补0
).withColumn(
    "remain_after_hour",
    F.col("remain_after_day") % 3600
).withColumn(
    "minute_part",
    F.lpad(F.floor(F.col("remain_after_hour") / 60).cast("string"), 2, "0")  # 拆分分钟部分:1分钟=60秒,不足2位补0
).withColumn(
    "second_total",
    F.col("remain_after_hour") % 60
).withColumn(
    "second_part",
    F.lpad(F.floor(F.col("second_total")).cast("string"), 2, "0")  # 拆分秒整数部分,不足2位补0
).withColumn(
    "micro_part",
    F.lpad(F.round((F.col("second_total") - F.floor(F.col("second_total"))) * 1000).cast("int").cast("string"), 3, "0") + F.lit("0000")  # 拼接毫秒+后4位0,匹配目标格式
).withColumn(
    "final_result",
    F.concat_ws(
        ".",
        F.col("day_part"),
        F.concat_ws(":", F.col("hour_part"), F.col("minute_part"), F.col("second_part")),
        F.col("micro_part")
    )
)

# 校验结果
df.select("ts", "expectedValue", "final_result").show(truncate=False)

运行结果

执行后final_result列返回值为12.22:05:38.3910000,和预期值完全一致。

内容的提问来源于stack exchange,提问作者John Stud

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 20:18:18