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

2022-09-01 21:48:04

我有这个代码:

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

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

为什么?这对我来说没有多大意义。有没有另一种设置可以使其更加严格?


答案 1

20128年是有效的一年,我想Java希望世界能活得那么久。

如果图案字母的数量超过 2,则无论数字位数如何,都会按字面解释年份。

参考。

如果要验证日期是否处于限制状态,可以定义一个日期并检查-

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");            
}

答案 2

查看 javadoc

年份:如果格式化程序的日历是公历,则应用以下规则。

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

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