为什么SimpleDateFormat(“MM / dd / yyyy”)将日期解析为10/20/20128?

时间:2013-08-30 13:40:21

标签: java date simpledateformat date-parsing

我有这段代码:

  DateFormat dateFormat = new SimpleDateFormat("MM/dd/yyyy");
  dateFormat.setLenient(false);
  Date date = dateFormat.parse("10/20/20128");

我希望dateFormat.parse调用抛出ParseException,因为我提供的年份是5个字符而不是4个,就像我定义的格式一样。但由于某些原因,即使将lenient设置为false,此调用也会返回Date对象10/20/20128。

为什么?这对我来说没什么意义。是否有其他设置使其更严格?

4 个答案:

答案 0 :(得分:39)

20128是一个有效的年份,Java希望全世界能够活得那么久。

  

如果模式字母的数量大于2,则年份为   无论数字位数如何,都按字面解释。

Reference.

如果要验证日期是否有限,可以定义一个并检查 -

SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");
Date maxDate = sdf.parse("01/01/2099");  // This is the limit

if(someDate.after(maxDate)){            
    System.out.println("Invalid date");            
}

答案 1 :(得分:11)

请参阅javadoc

  

年份:如果格式化程序的日历是格里高利历,那么   以下规则适用。

     
      
  • 对于格式化,如果模式字母的数量为2,则年份被截断为2位数;否则它被解释为数字。
  •   
  • 对于解析,如果模式字母的数量大于2,则按年度字面解释,无论数字位数如何。   所以使用模式“MM / dd / yyyy”,“01/11/12”解析到1月11日,12日   A.D。
  •   
  • 对于使用缩写年份模式(“y”或“yy”)进行解析,SimpleDateFormat必须解释相对于某些的缩写年份   世纪。它通过将日期调整到80年之前来实现   并且在创建SimpleDateFormat实例之后20年。   例如,使用“MM / dd / yy”和SimpleDateFormat的模式   在1997年1月1日创建的实例,字符串“01/11/12”将是
      解释为2012年1月11日,而字符串“05/04/64”将是
      解释为1964年5月4日。在解析期间,只有字符串组成
      正好由Character.isDigit(char)定义的两位数字   解析为默认世纪。任何其他数字字符串,例如
      一位数字符串,三位或更多位数字符串或两位数字符串   这不是所有数字(例如,“ - 1”),按字面解释   所以使用相同的模式解析“01/02/3”或“01/02/003”   1月2日,3日。同样,“01/02 / -3”被解析为公元前1月2日。
  •   
  • 否则,将应用特定于日历系统的表单。对于格式化和解析,如果模式字母的数量是4或
      更多,使用日历特定的长形式。否则,日历
      使用特定的简短或缩写形式。
  •   

因此,它会读取最后/之后的所有字符作为年份。

答案 2 :(得分:7)

请参阅java.text.SimpleDateFormat API,模式字母y:对于解析,如果模式字母的数量大于2,则无论数字位数如何,都会按字面解释年份。

答案 3 :(得分:1)

在java中使用SimpleDateFormat,您可以实现许多人类可读的格式。请考虑以下代码段:

        Date curDate = new Date();

        SimpleDateFormat format = new SimpleDateFormat("yyyy/MM/dd");

        String DateToStr = format.format(curDate);
        System.out.println(DateToStr);

        format = new SimpleDateFormat("dd-M-yyyy hh:mm:ss");
        DateToStr = format.format(curDate);
        System.out.println(DateToStr);

        format = new SimpleDateFormat("dd MMMM yyyy zzzz", Locale.ENGLISH);
        DateToStr = format.format(curDate);
        System.out.println(DateToStr);

        format = new SimpleDateFormat("E, dd MMM yyyy HH:mm:ss z");
        DateToStr = format.format(curDate);
        System.out.println(DateToStr);

查看各种格式生成的各种输出:

2014年5月11日

11-5-2014 11:11:51

2014年5月11日东欧夏令时

Sun,2014年5月11日23:11:51 EEST

随意修改格式字符串,您可能会得到所需的结果。