You need to enable JavaScript to run this app. Spark中Excel读取的整数日期值如何正确转换为时间戳
优惠活动
大模型
产品
解决方案
定价
更多

Spark中Excel读取的整数日期值如何正确转换为时间戳

Excel整数日期值转Spark时间戳的正确方案

转换偏差的核心原因

两者的时间编码规则完全错位,没有对齐逻辑:

  • Excel的日期编码规则:以1900-01-01为逻辑起点,每过1天整数值加1,且内置了1900年闰年兼容bug(误将不存在的1900-02-29算作有效日期),整数值本身仅代表自然日偏移量,不携带时区、时间起点信息
  • Spark默认的整数转时间戳逻辑:对整数字段直接执行cast(xxx as timestamp)时,会将整数解析为自1970-01-01 00:00:00 UTC起累计的秒数,完全沿用Unix时间的计算规则。

对应到你遇到的场景:数值43517直接cast时,Spark会计算从1970年元旦开始累计43517秒的偏移,合计约12小时,结合本地时区差就会算出1970-01-01 09:06左右的结果,和预期的2019年日期偏差极大。

可直接落地的转换实现

适配绝大多数Windows端Excel默认的1900日期系统,核心是对齐和Excel规则一致的基准时间:

经验证,取1899-12-30作为转换的基准时间,可完全兼容Excel的1900年闰年bug,无需手动计算2天的偏移量

转换的核心公式为:
目标时间戳 = 1899-12-30 00:00:00 + (Excel整数值 * 86400秒)(86400为单天的总秒数)

可以直接替换你原有selectExpr的逻辑,适配整数、带小数的Excel日期值:

val dfConverted = df.selectExpr(
  "timestamp('1899-12-30') + make_interval(seconds => date * 86400) as date"
)

如果习惯用DataFrame原生API,等价写法为:

import org.apache.spark.sql.functions._

val dfConverted = df.withColumn(
  "date",
  lit("1899-12-30").cast("timestamp") + col("date") * expr("INTERVAL 1 DAY")
)

特殊场景适配

  • 若处理的是Mac端老版本Excel的1904日期系统(逻辑起点为1904-01-01),仅需将代码中的基准日期从1899-12-30替换为1904-01-01,其余逻辑完全不变
  • 若Excel日期值带有小数部分(比如43517.5对应2019-04-16 12:00:00),上述公式可直接兼容,无需额外调整。

内容的提问来源于stack exchange,提问作者Felipe Troncoso Ortiz

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.11.02 18:57:01