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

PySpark to_timestamp解析差异:yyyy/MM/dd返回NULL,yyyy-MM-dd报错原因

PySpark日期解析行为差异问题解答

问题场景

在PySpark DataFrame中存在一个string类型的CallDate列,值格式为:

2008-04-01T00:00:00
2008-04-01T00:00:00

尝试使用pyspark.sql.functions.to_timestamp()转换时出现两种不同结果:

  • 执行以下代码,IncidentDate列全为NULL:
    df.withColumn('IncidentDate', to_timestamp(col('CallDate'), 'yyyy/MM/dd')).select('CallDate', 'IncidentDate').show()
    
    结果:
    +-------------------+------------+
    |           CallDate|IncidentDate|
    +-------------------+------------+
    |2008-04-01T00:00:00|        NULL|
    |2008-04-01T00:00:00|        NULL|
    +-------------------+------------+
    
  • 执行以下代码,直接抛出错误:
    df.withColumn('IncidentDate', to_timestamp(col('CallDate'), 'yyyy-MM-dd')).select('CallDate', 'IncidentDate').show()
    
    错误信息:
    Caused by: org.apache.spark.SparkUpgradeException: [INCONSISTENT_BEHAVIOR_CROSS_VERSION.PARSE_DATETIME_BY_NEW_PARSER] You may get a different result due to the upgrading to Spark >= 3.0:
    Fail to parse '2008-04-01T00:00:00' in the new parser. You can set "spark.sql.legacy.timeParserPolicy" to "LEGACY" to restore the behavior before Spark 3.0, or set to "CORRECTED" and treat it as an invalid datetime string.
    

原因分析

1. 使用yyyy/MM/dd返回NULL的原因

Spark日期解析器会严格匹配格式字符串与输入字符串的分隔符及整体结构:

  • 格式yyyy/MM/dd要求日期部分用斜杠/分隔,但输入字符串的日期部分用短横线-分隔,且后续带有T00:00:00的时间后缀,完全不符合指定格式。
  • 这种情况下,解析器判定输入无法匹配格式,触发容错逻辑返回NULL,不会抛出错误(这是Spark默认的解析失败处理方式)。

2. 使用yyyy-MM-dd抛出错误的原因

  • 输入字符串的前8位2008-04-01与格式yyyy-MM-dd的结构匹配,但字符串末尾存在额外的T00:00:00内容。
  • Spark 3.0+启用了新的日期解析器,默认要求输入字符串完全匹配格式字符串,不允许有未被格式覆盖的剩余字符。当解析到匹配的日期部分后发现还有剩余内容,解析器判定为无效的日期时间字符串,触发严格校验并抛出异常。
  • 旧版Spark(3.0之前)的解析器会忽略格式匹配后的剩余内容,不会报错,因此错误提示中提到可以通过设置spark.sql.legacy.timeParserPolicy参数切换到旧行为。

正确解析方式

使用完全匹配的格式字符串yyyy-MM-dd'T'HH:mm:ss,代码示例:

from pyspark.sql.functions import to_timestamp, col

df.withColumn('IncidentDate', to_timestamp(col('CallDate'), 'yyyy-MM-dd\'T\'HH:mm:ss')) \
  .select('CallDate', 'IncidentDate') \
  .show()

由于输入字符串符合ISO 8601标准,也可以省略格式参数,Spark会自动识别:

df.withColumn('IncidentDate', to_timestamp(col('CallDate'))) \
  .select('CallDate', 'IncidentDate') \
  .show()

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 02:10:42