PySpark中如何将多种混合格式的字符串日期转换为正确的目标日期格式
问题原因
coalesce 会按参数顺序返回第一个非空值,你当前的代码将yyyy-MM-dd、yyyy/MM/dd这类4位年份格式放在最前面,解析22-03-24、12/03/20这类短日期时,会误将前两位识别为公元纪年的年份,生成0022、0012这类异常日期,导致后续正确的两位年份格式不会被匹配到。
解决方案
方案1:调整匹配优先级+异常过滤(兼容全Spark版本)
优先匹配4位完整年份的格式,再匹配两位年份格式,同时过滤掉年份小于1970的无效解析结果:
from pyspark.sql import functions as F from pyspark.sql.functions import col spark.sql("set spark.sql.legacy.timeParserPolicy=LEGACY") sdf = df.withColumn("c1", F.to_date(F.unix_timestamp(df.Date,'MM-dd-yyyy').cast('timestamp'))) \ .withColumn("c2", F.to_date(F.unix_timestamp(df.Date,'MM/dd/yyyy').cast('timestamp'))) \ .withColumn("c3", F.to_date(F.unix_timestamp(df.Date,'dd-MM-yy').cast('timestamp'))) \ .withColumn("c4", F.to_date(F.unix_timestamp(df.Date,'dd/MM/yy').cast('timestamp'))) \ .withColumn("c5", F.to_date(F.unix_timestamp(df.Date,'yyyy-MM-dd').cast('timestamp'))) \ .withColumn("c6", F.to_date(F.unix_timestamp(df.Date,'yyyy/MM/dd').cast('timestamp'))) sdf = sdf.withColumn("result", F.coalesce( F.when(F.year("c1") >= 1970, col("c1")), F.when(F.year("c2") >= 1970, col("c2")), F.when(F.year("c3") >= 1970, col("c3")), F.when(F.year("c4") >= 1970, col("c4")), F.when(F.year("c5") >= 1970, col("c5")), F.when(F.year("c6") >= 1970, col("c6")) ))
方案2:多格式数组匹配(Spark 3.0+推荐)
Spark 3.0及以上版本的to_date函数支持直接传入按优先级排序的格式数组,会自动跳过解析失败的结果,代码更简洁:
from pyspark.sql import functions as F from pyspark.sql.functions import col sdf = df.withColumn("result", F.to_date(col("Date"), ["MM-dd-yyyy", "MM/dd/yyyy", "dd-MM-yy", "dd/MM/yy", "yyyy-MM-dd", "yyyy/MM/dd"] ))
最终正确结果
| Date | result |
|---|---|
| 12-21-2021 | 2021-12-21 |
| 04-23-2021 | 2021-04-23 |
| 22-03-24 | 2024-03-22 |
| 12/03/20 | 2020-03-12 |
内容的提问来源于stack exchange,提问作者gm tom
相关产品推荐
相关产品推荐

