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

如何在PySpark中使用to_date转换含荷兰语月份缩写的多格式日期字符串

荷兰语格式日期字符串转DateType最优方案

现有实现可优化点

现有自定义UDF的实现可以满足需求,但存在两个可优化点:

  1. UDF会带来额外的序列化/反序列化开销,性能弱于Spark原生函数
  2. 原有代码存在语法错误:to_date的格式参数错误传入了UDF内,实际应该作为to_date的第二个参数

原生函数实现方案(推荐)

Spark 3.0及以上版本的to_date/to_timestamp原生支持指定locale,无需自定义映射字典,同时自带灵活格式匹配能力:

  • d格式符自动兼容1位或2位天数
  • MMM格式符可匹配本地化月份缩写,搭配locale参数即可解析荷兰语月份
  • yy格式符自动兼容2位/4位年份,无需手动补前缀

实现代码

from pyspark.sql import functions as F

# 测试数据
df = spark.createDataFrame([
 ["2-feb-1966"],
 ["05-mei-1974"],
 ["3-mrt-83"],
 ["05-mrt-1983"],
 ["12-jun-75"]
]).toDF("DateOfBirth")

# 原生解析逻辑
df = df.withColumn(
    "DateOfBirth_new",
    F.to_date(
        F.col("DateOfBirth"),
        format="d-MMM-yy",
        options={"locale": "nl-NL"}
    )
)

2位年份世纪补全规则调整

如果需要固定将2位年份补前缀19,可额外加一层判断逻辑:

df = df.withColumn(
    "DateOfBirth_new",
    F.when(
        F.year(F.col("DateOfBirth_new")) < 1900,
        F.to_date(F.concat(F.lit("19"), F.date_format(F.col("DateOfBirth_new"), "yy-MM-dd")), "yyyy-MM-dd")
    ).otherwise(F.col("DateOfBirth_new"))
)

如果业务中存在2000年后出生的用户,可以根据业务范围调整补全规则,比如将小于30的2位年份补20,大于等于30的补19即可。

低版本Spark兼容方案

如果使用的Spark版本低于3.0,不支持locale参数,可以继续使用原有UDF,修正语法错误后即可正常运行:

import pyspark.sql.types as T

@F.udf(T.StringType())
def convert_date(s):
    month_dict = {"jan":"01", "feb":"02", "mrt":"03", "apr":"04", "mei":"05", "jun":"06", "jul":"07", "aug":"08", "sep":"09", "okt":"10", "nov":"11", "dec":"12" }
    day, month, year = s.split("-")
    if len(day) == 1:
        day = '0' + day
    if len(year) < 4:
        year = '19' + year
    return  day + "-" + month_dict[month] + "-" + year
  
df = df.withColumn('DateOfBirth_new', F.to_date(convert_date(F.col("DateOfBirth")), "dd-MM-yyyy"))

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 04:48:02