忽然笑
如@Maglob所示,基本方法是使用SimpleDateFormat.Analysis..这将捕获无效的日/月组合,如2008-02-31。然而,在实践中,这是不够的,因为SimpleDateFormat.Analysis是非常自由的。你可能会关注两种行为:日期字符串中的无效字符令人惊讶的是,2008-02-2x将“传递”为一个有效日期,例如locale Format=“yyyy-mm-dd”。即使是假的。年份:2位,3位还是4位?您还可能希望强制使用4位数的年份,而不是允许默认的SimpleDateFormat行为(根据格式是“yyy-mm-dd”还是“yy-mm-dd”,这将以不同的方式解释“12-02-31”)。标准库的严格解决方案因此,完整的字符串到日期测试可能如下所示:regex匹配的组合,然后强制日期转换。正则表达式的诀窍是使它对地区友好。 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);注意,regex假定格式字符串仅包含日、月、年和分隔符字符。除此之外,格式可以是任何区域设置格式:“d/mm/yy”、“yyyy-mm-dd”,等等。可以获得当前区域设置的格式字符串,如下所示:Locale locale = Locale.getDefault();SimpleDateFormat sdf = (SimpleDateFormat)DateFormat.getDateInstance(DateFormat.SHORT, locale );String format = sdf.toPattern();朱达时间-更好的选择?我听说过Joda时间最近我想比较一下。两点:与SimpleDateFormat不同,对日期字符串中的无效字符严格要求似乎更好还没有办法用它来执行4位数的年份(但我想您可以自己创建自己的年份)。DateTimeFormat为此目的)使用起来非常简单: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;}