PySpark selectExpr中to_date默认截断日期至年?如何规避及异常处理
问题原因与解决办法
问题根源
这不是预期行为,核心问题是你拼接日期字符串的方式错误:
当nxt_yr为2023时,boy = str(nxt_yr)+'01-01'会生成202301-01,这个字符串不符合yyyy-MM-dd的格式要求(正确格式应为2023-01-01,年份和月份间缺少横杠)。
加上你开启了LEGACY时间解析策略,Spark会对格式错误的日期做容错解析,最终错误地解析为当年年初日期。
解决办法
1. 修正字符串拼接格式
直接在年份和月份间添加横杠,生成符合要求的日期字符串:
boy = f"{nxt_yr}-01-01" eoy = f"{nxt_yr}-12-31" df_final = df_demo.selectExpr( "to_date('{}','yyyy-MM-dd') as strt_dt".format(boy), "to_date('{}','yyyy-MM-dd') as end_dt".format(eoy) ) spark.sql("set spark.sql.legacy.timeParserPolicy = LEGACY") df_final.show(1)
2. 使用Spark内置日期函数(更可靠)
无需手动拼接字符串,直接用Spark的日期函数生成当年第一天和最后一天,避免格式错误:
# 使用make_date直接构造日期 df_final = df_demo.selectExpr( f"make_date({nxt_yr}, 1, 1) as strt_dt", f"make_date({nxt_yr}, 12, 31) as end_dt" ) # 或者用日期截断和偏移函数 df_final = df_demo.selectExpr( f"date_trunc('year', to_date('{nxt_yr}-01-01', 'yyyy-MM-dd')) as strt_dt", f"last_day(add_months(to_date('{nxt_yr}-01-01', 'yyyy-MM-dd'), 11)) as end_dt" ) df_final.show(1)
3. 建议关闭LEGACY解析模式
如果不需要兼容旧代码,建议关闭LEGACY模式,让Spark对错误格式的日期直接抛出异常,方便快速定位问题:
spark.sql("set spark.sql.legacy.timeParserPolicy = CORRECTED")
内容的提问来源于stack exchange,提问作者Venu gupta
相关产品推荐
相关产品推荐

