Apache Spark 3.0(Java):不修改配置不抛异常验证日期列
解决方案
推荐方案:使用try_to_date(Spark 3.0+)
Spark 3.0及以上版本提供了try_to_date函数,它在日期解析失败时返回null而非抛出异常,完全适配你的需求,且无需修改全局配置:
import org.apache.spark.sql.functions; Dataset<Row> newDs = dataset.filter(functions.try_to_date(dataset.col("C1"), "dd-MM-yyyy").isNotNull());
这个函数是Spark原生实现,性能最优,且严格遵循当前的timeParserPolicy规则,是合规高效的首选方案。
兼容低版本Spark:正则预过滤 + to_date
如果你的Spark版本低于3.0,先通过正则过滤掉格式不匹配的字符串,避免to_date抛出异常,再校验日期有效性:
- 正则过滤格式:筛选出符合
[1-2位数字]-[1-2位数字]-[4位数字]格式的行(若严格要求两位日/月,正则改为^\\d{2}-\\d{2}-\\d{4}$):
Dataset<Row> regexFiltered = dataset.filter(functions.regexp_extract(dataset.col("C1"), "^\\d{1,2}-\\d{1,2}-\\d{4}$", 0).notEqual(""));
- 校验日期有效性:对过滤后的数据集用
to_date判断是否为有效日期:
Dataset<Row> newDs = regexFiltered.filter(functions.to_date(regexFiltered.col("C1"), "dd-MM-yyyy").isNotNull());
备选:自定义UDF
若上述方案均不可行,可编写UDF在Java层处理日期解析,捕获异常返回布尔值:
import org.apache.spark.sql.api.java.UDF1; import java.time.LocalDate; import java.time.format.DateTimeFormatter; import java.time.format.DateTimeParseException; // 注册UDF,判断字符串是否符合指定日期格式 spark.udf().register("isValidDate", (UDF1<String, Boolean>) dateStr -> { if (dateStr == null) return false; try { LocalDate.parse(dateStr, DateTimeFormatter.ofPattern("dd-MM-yyyy")); return true; } catch (DateTimeParseException e) { return false; } }, org.apache.spark.sql.types.DataTypes.BooleanType); // 使用UDF过滤 Dataset<Row> newDs = dataset.filter("isValidDate(C1)");
注意:UDF性能略逊于原生函数,仅作为兜底方案使用。
内容的提问来源于stack exchange,提问作者eddie
相关产品推荐
相关产品推荐

