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

PySpark字符串转日期年份映射问题:如何修正两位年份转换结果

解决PySpark中两位年份解析的世纪映射问题

你的问题在于使用to_date解析dd-MMM-yy格式的日期时,PySpark依赖的Java SimpleDateFormat默认的两位年份映射规则不符合业务预期——默认规则会基于当前年份的 pivot 值(通常为当前年份减80)自动分配世纪,导致09-Aug-96被解析为2096-08-09而非期望的1996-08-09。

以下是两种精准控制两位年份映射的解决方案:

方案一:手动拼接年份字符串后解析(固定规则)

直接指定两位年份对应的世纪区间,比如约定:

  • 00-23 → 2000-2023
  • 24-99 → 1924-1999
from pyspark.sql import SparkSession
from pyspark.sql.functions import to_date, substring, lit, concat, when, date_format

# 初始化SparkSession
spark = SparkSession.builder.getOrCreate()

# 示例数据
data = [("09-Aug-96",), ("05-Sep-23",)]
df = spark.createDataFrame(data, ["date_string"])

# 自定义两位年份映射逻辑
df = df.withColumn(
    "two_digit_year",
    substring("date_string", -2, 2).cast("int")
).withColumn(
    "full_date_str",
    concat(
        substring("date_string", 1, 6),  # 截取"dd-MMM-"部分
        when("two_digit_year" <= 23, lit("20")).otherwise(lit("19")),  # 选择世纪前缀
        substring("date_string", -2, 2)  # 拼接两位年份
    )
).withColumn(
    "date",
    to_date("full_date_str", "dd-MMM-yyyy")  # 按完整格式解析为日期类型
).withColumn(
    "formatted_date",
    date_format("date", "dd-MM-yyyy")  # 格式化为目标字符串
)

# 查看结果
df.select("date_string", "date", "formatted_date").show(truncate=False)

执行结果:

+-----------+----------+--------------+
|date_string|date      |formatted_date|
+-----------+----------+--------------+
|09-Aug-96  |1996-08-09|09-08-1996    |
|05-Sep-23  |2023-09-05|05-09-2023    |
+-----------+----------+--------------+

方案二:解析后动态调整年份(适配当前时间)

如果需要根据当前年份动态调整映射规则,比如解析后的年份超过当前年份+20时,自动减去100年:

from pyspark.sql import SparkSession
from pyspark.sql.functions import to_date, year, current_date, add_months, date_format, when

spark = SparkSession.builder.getOrCreate()

data = [("09-Aug-96",), ("05-Sep-23",)]
df = spark.createDataFrame(data, ["date_string"])

# 先按默认规则解析日期
df = df.withColumn("raw_date", to_date("date_string", "dd-MMM-yy"))

# 动态调整年份:若解析年份超过当前年份+20,减去100年
current_year = year(current_date())
df = df.withColumn(
    "adjusted_date",
    when(year("raw_date") > current_year + 20, add_months("raw_date", -1200)).otherwise("raw_date")
).withColumn(
    "formatted_date",
    date_format("adjusted_date", "dd-MM-yyyy")
)

df.select("date_string", "adjusted_date", "formatted_date").show(truncate=False)

你可以根据业务需求修改阈值(比如把current_year + 20改为固定年份2050),或者调整映射区间的分界值(比如将方案一中的23改为30,覆盖更多20xx年份)。

内容的提问来源于stack exchange,提问作者Ramineni Ravi Teja

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 12:55:02