如何在Java中检查日期的健全性
2022-09-01 14:49:30
我感到奇怪的是,在Java中创建对象的最明显方法已被弃用,并且似乎已经被“取代”为不太明显的宽松日历。Date
如何检查以日、月和年的组合给出的日期是否为有效日期?
例如,2008-02-31(如 yyyy-mm-dd 中所示)将是无效日期。
我感到奇怪的是,在Java中创建对象的最明显方法已被弃用,并且似乎已经被“取代”为不太明显的宽松日历。Date
如何检查以日、月和年的组合给出的日期是否为有效日期?
例如,2008-02-31(如 yyyy-mm-dd 中所示)将是无效日期。
Key is df.setLenient(false);.对于简单的案例来说,这绰绰有余。如果你正在寻找一个更健壮(我怀疑)和/或替代库,如joda-time,那么看看用户“tardate”的答案
final static String DATE_FORMAT = "dd-MM-yyyy";
public static boolean isDateValid(String date)
{
try {
DateFormat df = new SimpleDateFormat(DATE_FORMAT);
df.setLenient(false);
df.parse(date);
return true;
} catch (ParseException e) {
return false;
}
}
如@Maglob所示,基本方法是使用 SimpleDateFormat.parse 测试从字符串到日期的转换。这将捕获无效的日/月组合,如 2008-02-31。
然而,在实践中,这很少足够,因为SimpleDateFormat.parse是非常自由的。您可能会关注两种行为:
日期字符串中的字符无效令人惊讶的是,2008-02-2x将“传递”为有效日期,例如,区域设置格式= “yyyy-MM-dd”。即使 islenient==false。
年份:2、3 或 4 位数字?您可能还希望强制实施 4 位数年份,而不是允许默认的 SimpleDateFormat 行为(根据您的格式是“yyyy-MM-dd”还是“yy-MM-dd”,这将对“12-02-31”有不同的解释)
因此,完整的字符串到日期测试可能如下所示:正则表达式匹配的组合,然后是强制日期转换。正则表达式的诀窍是使其对区域设置友好。
Date parseDate(String maybeDate, String format, boolean lenient) {
Date date = null;
// test date string matches format structure using regex
// - weed out illegal characters and enforce 4-digit year
// - create the regex based on the local format string
String reFormat = Pattern.compile("d+|M+").matcher(Matcher.quoteReplacement(format)).replaceAll("\\\\d{1,2}");
reFormat = Pattern.compile("y+").matcher(reFormat).replaceAll("\\\\d{4}");
if ( Pattern.compile(reFormat).matcher(maybeDate).matches() ) {
// date string matches format structure,
// - now test it can be converted to a valid date
SimpleDateFormat sdf = (SimpleDateFormat)DateFormat.getDateInstance();
sdf.applyPattern(format);
sdf.setLenient(lenient);
try { date = sdf.parse(maybeDate); } catch (ParseException e) { }
}
return date;
}
// used like this:
Date date = parseDate( "21/5/2009", "d/M/yyyy", false);
请注意,正则表达式假定格式字符串仅包含日、月、年和分隔符。除此之外,格式可以是任何区域设置格式:“d/MM/yy”、“yyyy-MM-dd”等。当前区域设置的格式字符串可以按如下方式获取:
Locale locale = Locale.getDefault();
SimpleDateFormat sdf = (SimpleDateFormat)DateFormat.getDateInstance(DateFormat.SHORT, locale );
String format = sdf.toPattern();
我最近一直在听说joda时间,并认为我会比较。两点:
它使用起来非常简单:
import org.joda.time.format.*;
import org.joda.time.DateTime;
org.joda.time.DateTime parseDate(String maybeDate, String format) {
org.joda.time.DateTime date = null;
try {
DateTimeFormatter fmt = DateTimeFormat.forPattern(format);
date = fmt.parseDateTime(maybeDate);
} catch (Exception e) { }
return date;
}