如何使用Apache Spark将含两位年份的字符串转换为正确日期?
解决Spark SQL两位年份解析为未来日期的问题
以下是几种更合理的处理方式,无需后期手动减100年:
1. 设置全局年份解析阈值(Spark 3.0+)
Spark 3.0及以上版本支持通过配置参数指定两位年份的解析阈值,超过阈值的年份会被解析为19xx,低于则为20xx。在Spark SQL中执行以下命令设置全局规则:
SET spark.sql.datetime.parser.year2000Threshold=90;
设置后,执行select to_date('1/1/94', 'm/d/yy')就会返回1994-01-01——因为94≥90,自动归为19xx年。你可以根据业务需求调整阈值(比如设为50,把50及以上的两位年份解析为19xx)。
2. 手动拼接四位年份再解析
如果使用的Spark版本较低,不支持全局阈值配置,可以手动处理字符串,将两位年份转为四位后再解析:
SELECT to_date( CONCAT( SUBSTR('1/1/94', 1, LENGTH('1/1/94') - 2), CASE WHEN CAST(SUBSTR('1/1/94', -2) AS INT) >= 90 THEN '19' ELSE '20' END, SUBSTR('1/1/94', -2) ), 'm/d/yyyy' ) AS parsed_date;
这个逻辑通过截取年份部分,判断后拼接19或20前缀,再用四位年份的格式解析,精准控制年份归属。
3. 使用自定义UDF(适用于复杂场景)
如果有大量不同格式的日期需要统一处理,可以编写自定义UDF封装年份解析逻辑,示例如下:
// Scala示例,注册UDF spark.udf.register("parse_two_digit_year", (dateStr: String, format: String) => { val df = new java.text.SimpleDateFormat(format) df.set2DigitYearStart(java.util.Calendar.getInstance().apply(java.util.Calendar.YEAR, 1990)) df.parse(dateStr) })
之后在Spark SQL中直接调用:
SELECT parse_two_digit_year('1/1/94', 'MM/dd/yy') AS parsed_date;
这种方式适合需要自定义复杂解析规则的场景。
内容的提问来源于stack exchange,提问作者dudeinco
相关产品推荐
相关产品推荐

