Java自定义方法校验日期字符串格式与合法性
在进行数据交互时,仅依赖 SimpleDateFormat 的默认行为可能无法准确拦截非法日期(例如允许 2023-02-30 这样的无效时间)。本文将提供一个完整的 Java 工具类,利用“解析后重新格式化并与原字符串比对”的方法,实现对多种日期和时间格式的严格合法性校验。
为什么要使用双重校验?
java.text.SimpleDateFormat 默认开启了 “Lenient(宽松模式)”。这意味着如果你传入 "2023-13-45",它可能会将其转换为下一年的有效时间,而不是报错抛出异常。对于需要严格合规的场景(如表单提交、接口入参),这种隐式转换可能导致严重的数据错误。因此,我们需要增加一步:将解析出的 Date 对象再次格式化为字符串,并确认其与原始输入完全一致。
准备条件与完整类结构
该方法不依赖任何第三方库,直接集成到现有项目中即可使用。核心逻辑位于静态方法 isLegalDate 中,主要包含两个检查:
- 长度与空值检查:确保传入的字符串非空且长度与指定格式匹配。
- 内容一致性检查:确保解析后的日期与原字符串描述的是同一个时间点。
第1步:编写校验工具类
以下是可以直接运行的完整 IsLegalDate 类。该类包含了 main 方法用于演示五种常见场景的调用方式。
package com.shucha.deveiface.biz.test;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* @author tqf
* @Description 时间格式校验工具
*/
public class IsLegalDate {
public static void main(String[] args) {
// 1. 验证 yyyy-MM-dd HH:mm:ss 格式
String dateStr = "2020-01-25 12:36:45";
System.out.println("Date Validation: " + isLegalDate(dateStr.length(), dateStr, "yyyy-MM-dd HH:mm:ss"));
// 2. 验证 yyyy-MM-dd 格式
String yearMonthday = "2020-01-01";
System.out.println("Day Validation: " + isLegalDate(yearMonthday.length(), yearMonthday, "yyyy-MM-dd"));
// 3. 验证 yyyy-MM 格式
String yearMonth = "2020-02";
System.out.println("Month Validation: " + isLegalDate(yearMonth.length(), yearMonth, "yyyy-MM"));
// 4. 验证 yyyy 格式
String year = "2020";
System.out.println("Year Validation: " + isLegalDate(year.length(), year, "yyyy"));
// 5. 验证 HH:mm:ss 格式
String hms = "12:36:89"; // 注:89秒是非法时间,应返回 false
System.out.println("Time Validation: " + isLegalDate(hms.length(), hms, "HH:mm:ss"));
}
/**
* 校验日期格式是否合法
*
* @param length 目标字符串的长度
* @param sDate 待校验的日期字符串
* @param format 期望的时间格式
* @return 如果格式正确且内容为真(非伪日期则true,否则false)
*/
public static boolean isLegalDate(int length, String sDate, String format) {
int legalLen = length;
// 第一步:基础长度和空值校验
if ((sDate == null) || (sDate.length() != legalLen)) {
return false;
}
DateFormat formatter = new SimpleDateFormat(format);
try {
// 第二步:尝试解析为Date对象
Date date = formatter.parse(sDate);
// 第三步:再次格式化为String,并对比原字符串
// 这是判断"2月30日"等伪时间的关键
return sDate.equals(formatter.format(date));
} catch (Exception e) {
// 解析失败(如格式完全不匹配)或内部逻辑冲突
return false;
}
}
}
运行结果与图示分析
上述代码在控制台执行时,前四项输入均为有效时间,输出应为 true。第五项中,由于 "12:36:89" 中的秒数超过了60,属于逻辑上的非法时间,因此最终比对会失败,输出 false。
程序实际运行的输出截图如下,展示了不同时间格式的校验效果:
常见问题排错
- 为什么不用正则表达式?
正则可以检查格式(如是否有横杠、冒号),但无法检查内容的合法性(如每个月的天数、闰年二月)。本方案结合了解析器的逻辑判断能力。 - 性能影响
虽然比单纯的正则稍慢(因为涉及解析和二次格式化),但对于普通的业务逻辑校验,其性能损耗可忽略不计。
本站声明
本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。













