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

Spark Scala DataFrame按周数取周日周末日期 第53周返回null如何解决

问题根因
  1. 你当前用to_date(col("year_week_number"), "w/yyyy")解析53/2020返回null,核心是两点:
    • Spark默认周起始日为周日,和你要求的周一规则不匹配,导致默认规则下2020年的周数上限为52,无法解析第53周
    • 原有闰年判断后加7/14天的逻辑和周数计算无关,属于冗余错误逻辑,周数是否存在第53周和闰年无直接关联,由当年1月1日的星期属性决定
  2. 你需要的2020年第53周(周一到周日)的日期范围是2020-12-28至2021-01-03,周末为2021-01-03,符合业务预期。
解决方案

第一步:配置周起始规则

首先设置Spark SQL全局参数,指定周起始日为周一,和你的业务规则对齐:

// 参数值1代表周一,7代表周日(Spark默认值)
spark.conf.set("spark.sql.weekStart", "1")

第二步:修正日期计算逻辑

删除冗余的闰年判断逻辑,解析周数后加6天即可得到当周周日(周一是第1天,加6天为周日):

case class Data(id:Int,weekNumber:String)
var stgDF = Seq(Data(100,"53/2020")).toDF()
val weekNumber = "53/2020"

stgDF = stgDF
  .withColumn("year_week_number", lit(weekNumber))
  .withColumn("dsupp_trans_dt", date_add(to_date(col("year_week_number"), "w/yyyy"), 6))

stgDF.show(false)

输出验证

调整后输出结果如下,符合预期:

+---+----------+----------------+--------------+
|id |weekNumber|year_week_number|dsupp_trans_dt|
+---+----------+----------------+--------------+
|100|53/2020   |53/2020         |2021-01-03    |
+---+----------+----------------+--------------+

用52/2020测试也会得到你之前的正确结果2020-12-27,兼容原有正常场景。

Spark 2.x兼容方案

如果你使用的是没有spark.sql.weekStart参数的Spark 2.x版本,可以用自定义UDF实现周计算,不需要依赖全局配置:

import java.time.LocalDate
import java.time.temporal.WeekFields
import java.util.Locale

val getWeekendUdf = udf((weekYearStr: String) => {
  val Array(weekNum, year) = weekYearStr.split("/").map(_.toInt)
  val weekFields = WeekFields.of(Locale.CHINA) // 周起始为周一的区域规则
  val firstDayOfWeek = LocalDate.of(year, 1, 1)
    .`with`(weekFields.weekOfWeekBasedYear(), weekNum)
    .`with`(weekFields.dayOfWeek(), 1)
  firstDayOfWeek.plusDays(6).toString
})

// 调用UDF计算
stgDF = stgDF.withColumn("dsupp_trans_dt", to_date(getWeekendUdf(col("year_week_number"))))

内容的提问来源于stack exchange,提问作者Surender Raja

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.07 15:06:04