如何检查日期字符串的有效性?

在我的项目中,我需要检查日期字符串是否评估为正确的Date对象。 我决定允许yyyy-MM-dd和日期格式[(年,月,日)和(年,月,日,小时,分)]。 如何检查它们是否有效? 我的代码为“1980-01-01”和一些奇怪的日期(如3837.05.01)返回null,它们用逗号分隔一个字符串:

private Date parseDate(String date){ Date data = null; // yyy-mm-dd try { DateFormat df = DateFormat.getDateInstance(DateFormat.SHORT); df.setLenient(false); df.parse(date); return data; } catch (Exception e) { try{ int[] datArr = parseStringForDate(date); int len = datArr.length; // year, month, day if(len == 3){ return new Date(datArr[0], datArr[1], datArr[2]); } // year, montd, day, hours, mins else if(len ==5){ return new Date(datArr[0], datArr[1], datArr[2], datArr[3], datArr[4]); } // year, month, day, hours, mins, secs else if(len == 6){ return new Date(datArr[0], datArr[1], datArr[2], datArr[3], datArr[4], datArr[5]); } else { return data; } } catch (Exception f){ return data; } } } private int[] parseStringForDate(String s){ String[] sArr = s.split(","); int[] dateArr = new int[sArr.length]; for(int i=0; i< dateArr.length; i++){ dateArr[i] = Integer.parseInt(sArr[i]); } return dateArr; } 

我记得我不得不从年份中减去1900,但我也看到月份不同等等,我想避免从日期字符串中检查我的数组的每个元素。 是否可以在Calendar或日期对象中自动解析它们?

您可以为此不同的String格式构造SimpleDateFormat对象(如果无法将参数解析为有效日期,则返回null ):

 // Initializing possibleFormats somewhere only once SimpleDateFormat[] possibleFormats = new SimpleDateFormat[] { new SimpleDateFormat("yyyy-MM-dd"), new SimpleDateFormat("yyyy,MM,dd"), new SimpleDateFormat("yyyy,MM,dd,HH,mm") }; for (SimpleDateFormat format: possibleFormats) { format.setLenient(false); } // initializing ends public Date parseDate(String date) { Date retVal = null; int index = 0; while (retVal == null && index < possibleFormats.length) { try { retVal = possibleFormats[index++].parse(date); } catch (ParseException ex) { /* Do nothing */ } } return retVal; } 

你这样做是错误的。 你应该使用SimpleDateFormat 。

 SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); try { Date test = sdf.parse(input); } catch (ParseException pe) { //Date is invalid, try next format } 

对于2017年或之后弹出的人来说,这是Java 8解决方案:

 private static DateTimeFormatter[] possibleFormats = { DateTimeFormatter.ofPattern("uuuu-MM-dd").withResolverStyle(ResolverStyle.STRICT), DateTimeFormatter.ofPattern("uuuu,MM,dd").withResolverStyle(ResolverStyle.STRICT), DateTimeFormatter.ofPattern("uuuu,MM,dd,HH,mm").withResolverStyle(ResolverStyle.STRICT), DateTimeFormatter.ofPattern("uuuu,MM,dd,HH,mm,ss").withResolverStyle(ResolverStyle.STRICT) }; public Optional parseDate(String date) { for (DateTimeFormatter format : possibleFormats) { try { LocalDate result = LocalDate.parse(date, format); return Optional.of(result); } catch (DateTimeParseException dtpe) { // ignore, try next format } } return Optional.empty(); } 

使用DateTimeFormatter ,即使在multithreading环境中也可以安全地让格式化器数组保持静态:与SimpleDateFormat不同, DateTimeFormatter是线程安全的。

LocalDate是没有时间的日期,因此如果字符串中存在任何小时和分钟,则它们将丢失。 要获得小时,分钟和秒数,您需要一个LocalDateTime ,然后您需要一些技巧来使解析在字符串中没有小时和分钟的情况下工作。 您可以尝试使用LocalDate.parse()LocalDateTime.parse() ,也可以构建一个格式化程序,当不在字符串中时,该格式化程序具有默认的小时数。 DateTimeFormatterBuilder可以做到这一点。

感谢Csaba_H和Steve Kuo,以展示最终结果。

 private Date parseDate(String date){ SimpleDateFormat[] possibleFormats = new SimpleDateFormat[] { new SimpleDateFormat("yyyy-MM-dd"), new SimpleDateFormat("yyyy,MM,dd"), new SimpleDateFormat("yyyy,MM,dd,HH,mm") }; Date retVal = null; for (SimpleDateFormat f: possibleFormats) { f.setLenient(false); try { retVal = f.parse(date); } catch (ParseException e) {} } return retVal; }