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

goe*_*goe 22 java date date-parsing simpledateformat

我有这个代码:

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

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

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

Saj*_*tta 40

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");            
}
Run Code Online (Sandbox Code Playgroud)

  • 如果您正在编写需要4位数年份的软件,请*使用"12/31/9999"作为您的`maxDate`.我们不需要另一个*Y21K*问题. (8认同)

Sot*_*lis 11

请参阅javadoc

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

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

因此,它将读取最后一个/年后的所有字符.


Evg*_*eev 7

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