日期年份值在无效时显示有效

时间:2018-08-11 15:03:44

标签: java validation date

我正在使用一个日期应用程序,用户将在其中输入日期并验证该日期。日期格式为dd/MM/yyyy。这是我的代码

import java.util.*;
import java.text.SimpleDateFormat;
import java.text.ParseException;

public class HelloWorld {
  public static void main(String[] args) {
 //Scanner sc = new Scanner(System.in);
  String dat = "02/1/2018";
  try {
             SimpleDateFormat df = new SimpleDateFormat("dd/MM/yyyy");
                df.setLenient(false);
                df.parse(dat);
                System.out.print("valid");
            } catch (ParseException e) {
                System.out.print("invalid");
            }

   }
 }

这很完美,可以验证我的日期,但是当我输入22/02/2-19之类的日期时也同样有效。但这应该是无效的,因为我的年份是2-19

3 个答案:

答案 0 :(得分:2)

java.time

您使用的是可怕的旧日期时间类,而这些类早已被 java.time 类所取代。

对于仅日期值,请使用仅日期类:LocalDate

使用DateTimeFormatter类定义格式设置模式。搜索堆栈溢出以获取更多讨论和示例,因为已经讨论了很多次。

解析时,陷阱DateTimeParseException以确定是否无效。

String input = "22/02/2-19";
DateTimeFormatter f = DateTimeFormatter.ofPattern( "dd/MM/uuuu" );
LocalDate ld = null;
try {
    ld = LocalDate.parse( input , f );
    System.out.println( "VALID: " + ld.toString() );
} catch ( DateTimeParseException e ) {
    System.out.println( "INVALID: " + input );
    e.printStackTrace();
}
  

无效:22/02 / 2-19

     

java.time.format.DateTimeParseException:无法在索引6处解析文本“ 22/02 / 2-19”……


关于 java.time

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

目前位于Joda-Timemaintenance mode项目建议迁移到java.time类。

要了解更多信息,请参见Oracle Tutorial。并在Stack Overflow中搜索许多示例和说明。规格为JSR 310

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

在哪里获取java.time类?

ThreeTen-Extra项目使用其他类扩展了java.time。该项目为将来可能在java.time中添加内容提供了一个试验场。您可能会在这里找到一些有用的类,例如IntervalYearWeekYearQuartermore

答案 1 :(得分:1)

根据SimpleDateFormat的{​​{3}}:

  

对于解析,如果模式字母的数量大于2,则将按字面意义解释年份,而不考虑位数。因此,使用模式“ MM / dd / yyyy”,“ 01/11/12”解析为公元1月11日

这就是为什么输入22/02/2-19不会引发解析异常的原因。它以2作为年份,而忽略其余部分。

答案 2 :(得分:0)

java.time

Basil Bourque’s excellent answer已经为您的问题提供了最佳解决方案。我不再重复。如果使用该答案,您希望像第一个示例02/1/2018一样接受1位数的月份,则应在格式模式字符串中仅给出一个M。然后101都将被接受。同样,一个d会在一个月的某天接受202

您的代码出了什么问题

SimpleDateFormat从字符串中读取尽可能多的字符以匹配格式模式,但很高兴不阅读所有内容。在第二个示例22/02/2-19中,它将22/02/2解析为周一1月2日00:00:00 CET 2的Date(具体结果取决于您的时区), 2016年前由于这是一个有效日期,因此不会引发任何异常。然后,它将忽略字符串的最后三个字符。