Java日期validation

我需要validation用户输入为有效日期。 用户可以输入dd / mm / yyyy或mm / yyyy(两者都有效)

validation我正在做的事情

try{ GregorianCalendar cal = new GregorianCalendar(); cal.setLenient(false); String []userDate = uDate.split("/"); if(userDate.length == 3){ cal.set(Calendar.YEAR, Integer.parseInt(userDate[2])); cal.set(Calendar.MONTH, Integer.parseInt(userDate[1])); cal.set(Calendar.DAY_OF_MONTH, Integer.parseInt(userDate[0])); cal.getTime(); }else if(userDate.length == 2){ cal.set(Calendar.YEAR, Integer.parseInt(userDate[1])); cal.set(Calendar.MONTH, Integer.parseInt(userDate[0])); cal.getTime(); }else{ // invalid date } }catch(Exception e){ //Invalid date } 

因为GregorianCalendar从0开始,30/01/2009或12/2009开始给出错误。

任何建议如何解决这个问题。

使用SimpleDateformat 。 如果解析失败则会抛出ParseException

 private Date getDate(String text) throws java.text.ParseException { try { // try the day format first SimpleDateFormat df = new SimpleDateFormat("dd/MM/yyyy"); df.setLenient(false); return df.parse(text); } catch (ParseException e) { // fall back on the month format SimpleDateFormat df = new SimpleDateFormat("MM/yyyy"); df.setLenient(false); return df.parse(text); } } 

使用SimpleDateFormatvalidationDate ,将setLenientvalidation为false

TL;博士

使用try - catch捕获从java.time类中的LocalDate.parseYearMonth.parse抛出的DateTimeParseException

java.time

现代方法使用java.time类。

YearMonth

对于没有每月的一年的月份,请使用YearMonth类。

如果可能,让您的用户使用标准ISO 8601格式进行数据输入: YYYY-MM 。 解析/生成字符串时, java.time类在默认情况下使用标准格式。

 YearMonth ym = YearMonth.parse( "2018-01" ) ; 

如果不可能,请指定格式设置模式。

 DateTimeFormatter f = DateTimeFormatter.ofPattern( "MM/uuuu" ) ; YearMonth ym = YearMonth.parse( "01/2018" , f ) ; 

要测试无效输入,请捕获exception。

 DateTimeFormatter f = DateTimeFormatter.ofPattern( "MM/uuuu" ) ; YearMonth ym = null ; try{ ym = YearMonth.parse( "01/2018" , f ) ; } catch ( DateTimeParseException e ) { // Handle faulty input … } 

LocalDate

对于仅限日期的值,没有时间和没有时区,请使用LocalDate类。

同样,如果可能,使用标准ISO 8601格式进行数据输入: YYYY-MM-DD

 LocalDate ld = LocalDate.parse( "2018-01-23" ) ; 

如果没有,请指定格式模式和exception陷阱,如上所示。

 DateTimeFormatter f = DateTimeFormatter.ofPattern( "dd/MM/uuuu" ) ; LocalDate ld = null ; try{ ld = LocalDate.parse( "23/01/2018" , f ) ; } catch ( DateTimeParseException e ) { // Handle faulty input … } 

结合

如果输入可以是仅日期或年 – 月,则测试输入的长度以确定哪个是哪个。

 int length = input.length() ; switch ( length ) { case 7 : … // Process as year-month using code seen above. case 10 : … // Process as date-only using code seen above. default: … // ERROR, unexpected input. } 

关于java.time

java.time框架内置于Java 8及更高版本中。 这些类取代了麻烦的旧遗留日期时间类,如java.util.DateCalendarSimpleDateFormat

现在处于维护模式的Joda-Time项目建议迁移到java.time类。

要了解更多信息,请参阅Oracle教程 。 并搜索Stack Overflow以获取许多示例和解释。 规范是JSR 310 。

您可以直接与数据库交换java.time对象。 使用符合JDBC 4.2或更高版本的JDBC驱动程序 。 不需要字符串,不需要java.sql.*类。

从哪里获取java.time类?

  • Java SE 8Java SE 9Java SE 10Java SE 11及更高版本 – 带有捆绑实现的标准Java API的一部分。
    • Java 9增加了一些小function和修复。
  • Java SE 6Java SE 7
    • 大多数java.timefunction都在ThreeTen- Backport中反向移植到Java 6和7。
  • Android的
    • 更高版本的Android捆绑java.time类的实现。
    • 对于早期的Android(<26), ThreeTenABP项目采用ThreeTen-Backport (如上所述)。 请参见如何使用ThreeTenABP ….

ThreeTen-Extra项目使用其他类扩展了java.time。 该项目是未来可能添加到java.time的试验场。 您可以在这里找到一些有用的课程,如IntervalYearWeekYearQuarter等。