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

如何在Spark单元测试中启用与生产一致的时间格式严格校验规则

解决方案

1. 单元测试初始化SparkSession时强制配置严格时间校验规则

核心是在单测的SparkSession初始化阶段,将spark.sql.legacy.timeParserPolicy设置为EXCEPTION,该配置会让Spark遇到无效的日期格式化/解析结果时直接抛出异常,和生产环境的校验行为完全对齐,从根源上避免测试和生产行为不一致的问题。
参考Scala单测初始化代码:

import org.apache.spark.sql.SparkSession
import org.scalatest.BeforeAndAfterAll
import org.scalatest.funsuite.AnyFunSuite

class DateFormatTest extends AnyFunSuite with BeforeAndAfterAll {
  private var spark: SparkSession = _

  override def beforeAll(): Unit = {
    spark = SparkSession.builder()
      .master("local[*]")
      .appName("DateFormatUnitTest")
      // 核心配置:强制启用严格时间解析校验,无效格式直接抛出异常
      .config("spark.sql.legacy.timeParserPolicy", "EXCEPTION")
      .getOrCreate()
    super.beforeAll()
  }

  override def afterAll(): Unit = {
    if (spark != null) spark.stop()
    super.afterAll()
  }
}

2. 构造覆盖边界日期的测试用例

由于DD是年积日标识,只有当日序超过当月最大天数时才会触发校验失败,因此测试数据需要包含下半年、年底的日期,确保能触发格式错误。
参考测试用例代码:

test("date format should not use invalid pattern DD") {
  import spark.implicits._
  // 构造会触发DD格式错误的测试数据:2021-10-19 对应的年积日是292
  val testDF = Seq("2021-10-19T14:27:12.577Z").toDF("timestamp_str")
    .selectExpr("to_timestamp(timestamp_str, \"yyyy-MM-dd'T'HH:mm:ss.SSS'Z'\") as timestamp")
  
  // 执行包含错误格式化的代码,此时会直接抛出SparkUpgradeException,单元测试失败
  testDF.selectExpr("concat(date_format(timestamp,\"yyyy-MM-DD'T'HH:mm:ss.SSS'Z'\")) as formatted_str")
    .collect()
}

3. 共享SparkSession配置(可选)

如果你的测试套件使用统一的SparkSession基类,直接把上述配置加到基类的SparkSession初始化逻辑中,即可让所有单测默认启用严格校验,无需每个测试单独配置。

根因修复方案

你代码中的格式错误是误用了年积日标识DD,替换为当月天数标识dd即可解决:
正确写法:concat(date_format(col("timestamp"),"yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"))

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 12:15:09