AWS Glue中PySpark两位年份字符串转日期年份识别错误如何解决
问题根因
- 代码写法错误:
to_date第二个参数是输入日期的解析格式,不能用来指定输出格式,嵌套两层to_date属于功能误用,输出指定格式的字符串应该用date_format函数。 - 运行环境版本差异:本地Jupyter的Spark版本和AWS Glue的Spark版本不一致,二者对2位年份的解析规则完全不同:
- Spark 2.x(对应Glue 2.0及更低版本)默认使用LEGACY时间解析策略,
yy格式的年份会直接拼接1900前缀,所以你示例中的45会被解析为1945。 - Spark 3.x默认使用CORRECTED策略,会根据当前时间动态判断2位年份属于20xx还是19xx,所以本地运行能得到你预期的2045。
- Spark 2.x(对应Glue 2.0及更低版本)默认使用LEGACY时间解析策略,
修复方案
方案1:修正写法+配置时间解析策略
先修正日期转换的逻辑,再给Glue任务添加Spark配置,指定使用CORRECTED时间解析策略即可对齐本地运行效果:
- 修正转换代码:
def cast_date_fields(df ): df = df.withColumn( "data_ok", # 先按输入格式解析为日期类型,再用date_format转成目标格式字符串 expr("date_format(to_date(mydate, 'ddMMyy'), 'yyyyMMdd')").cast('String') ) return df
- 在Glue任务的Spark参数配置中添加:
spark.sql.legacy.timeParserPolicy = CORRECTED
Glue 3.0及以上版本默认已经开启该配置,无需额外设置。
方案2:手动拼接年份前缀,彻底规避规则差异
如果你的业务场景中所有2位年份都属于20xx,直接拆分字符串手动拼接前缀最稳妥,完全不受版本、配置的影响:
def cast_date_fields(df ): df = df.withColumn( "data_ok", # 按位拆分原字符串,手动加20前缀后按目标格式拼接 expr("concat('20', substring(mydate, 5, 2), substring(mydate, 3, 2), substring(mydate, 1, 2))") ) return df
如果业务中同时存在19xx和20xx的年份,可以自行添加判断逻辑,比如年份小于50的归为20xx,大于等于50的归为19xx:
expr(""" concat( case when cast(substring(mydate, 5, 2) as int) < 50 then '20' else '19' end, substring(mydate, 5, 2), substring(mydate, 3, 2), substring(mydate, 1, 2) ) """)
内容的提问来源于stack exchange,提问作者Eriton Silva
相关产品推荐
相关产品推荐

