Java MM / dd / yy简单日期DateTimeFormatter的工作时间不超过2037

时间:2016-04-01 19:03:54

标签: java date jodatime

实际上,我发现MM/dd/yy日期格式有问题: 如果输入年份大于37,则年份格式反映为1937

即如果我输入02/05/37输入,那么当我将此日期打印到控制台时,日期会变为02/05/1937

如果他输入的时间少于02/05/37,那么工作正常。

Date startDate = new SimpleDateFormat("dd/MM/yy").parse("01/01/47");
System.out.println(startDate);

3 个答案:

答案 0 :(得分:5)

假设您正在使用SimpleDateFormat:它符合规范02/05/37被解析为02/05/1937。至少在接下来的一年左右......

Java SimpleDateFormat必须决定你的日期应该在哪个世纪。它通过将日期调整为创建SimpleDateFormat实例之前的80年和20年之后来实现此目的。 2037年是在当前日期(2016年)之前的80年内,因此它使用过去的时间。

答案 1 :(得分:4)

其他答案都是正确的。您需要了解SimpleDateFormat行为以承担您的预期世纪。

您正在使用旧的过时类。新推荐的类在此问题上有不同的行为。

java.time

Java 8及更高版本中内置的java.time框架取代了旧的java.util.Date& SimpleDateFormat类。

关于假设世纪的行为是不同的。在DateTimeFormatter课程中,一个两位数的世纪被解释为在21世纪,导致一年在2000至2099 范围内。

java.time类包括LocalDate,用于表示没有时间且没有时区的仅限日期的值。

String input = "02/01/47";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern( "dd/MM/yy" );
LocalDate localDate = LocalDate.parse( input , formatter );
  

2047年1月2日

顺便提一下,如果可能的话,提示:避免两位数年。引起的混乱和麻烦不值得节省两个字节和墨粉涂抹。

答案 2 :(得分:3)

如果你不提供世纪信息,那么它必须做出一个假设,并且它相当合理地假设你过去想要大多数日期,有一些未来日期,但不能太远,因为您更有可能想要事先约会,例如出生日期等。而且人们通常活到80岁左右。根据这一假设,到目前为止,对于任何给定的当前日期,过去的日期将比未来日期更多。

来自spec ...

  

使用缩写的年份模式进行解析(" 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)定义的两位数字   解析为默认世纪。任何其他数字字符串,例如a   一位数字符串,三位或更多位数字符串或两位数字符串   并非所有数字(例如," -1")都按字面解释。   所以" 01/02/3"或" 01/02 / 003"使用与Jan相同的模式进行解析   2,公元3年。同样," 01/02 / -3"被解析为公元前1月2日。

     

否则,将应用特定于日历系统的表单。对彼此而言   格式化和解析,如果模式字母的数量是4或更多,   使用日历特定的长格式。否则,特定于日历   使用简短或缩写形式。

因此,如果您要对此做些什么,那么您需要检查格式化日期是否在今天的日期之前(或者您选择的其他一些截止日期),并且只需添加100年在给定日期,如果您希望仅具有未来日期或超出默认日期之外的其他日期。