Java MM/dd/yy 简单日期 DateTimeFormatter 不适用于大于 2037
Java MM/dd/yy simple date DateTimeFormatter not working for greater than 2037
实际上,我发现 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);
假设您使用的是 SimpleDateFormat
:02/05/37 被解析为 02/05/1937 符合规范。至少在接下来的一年左右...
Java 的 SimpleDateFormat 必须决定您的日期应该在哪个世纪。它通过将日期调整为在创建 SimpleDateFormat 实例之前 80 年和之后 20 年内来实现。 2037 比当前日期 (2016) 早 80 年,因此它使用过去的时间。
如果您不提供世纪信息,那么它必须做出假设,并且相当合理地假设您将主要希望过去的日期,以及未来日期的一些范围,但不会太远,因为您更有可能想要更早的日期,例如出生日期等。而且人们通常能活到 80 岁左右。根据这个假设,对于任何给定的当前日期,过去的日期远远多于未来的日期。
来自 spec...
For parsing with the abbreviated year pattern ("y" or "yy"),
SimpleDateFormat must interpret the abbreviated year relative to some
century. It does this by adjusting dates to be within 80 years before
and 20 years after the time the SimpleDateFormat instance is created.
For example, using a pattern of "MM/dd/yy" and a SimpleDateFormat
instance created on Jan 1, 1997, the string "01/11/12" would be
interpreted as Jan 11, 2012 while the string "05/04/64" would be
interpreted as May 4, 1964. During parsing, only strings consisting of
exactly two digits, as defined by Character.isDigit(char), will be
parsed into the default century. Any other numeric string, such as a
one digit string, a three or more digit string, or a two digit string
that isn't all digits (for example, "-1"), is interpreted literally.
So "01/02/3" or "01/02/003" are parsed, using the same pattern, as Jan
2, 3 AD. Likewise, "01/02/-3" is parsed as Jan 2, 4 BC.
Otherwise, calendar system specific forms are applied. For both
formatting and parsing, if the number of pattern letters is 4 or more,
a calendar specific long form is used. Otherwise, a calendar specific
short or abbreviated form is used.
因此,如果您要对此进行处理,则需要检查格式化日期是否早于今天的日期(或您选择的其他截止日期),然后将给定日期加上 100 年, 如果您希望只有未来日期或超出默认日期的不同截止日期。
其他答案正确。您需要了解 SimpleDateFormat
假设您预期世纪的行为。
您使用的是过时的 classes。新推荐的 classes 在这个问题上有不同的行为。
java.time
java.time 框架内置于 Java 8 及更高版本取代了旧的 java.util.Date 和 SimpleDateFormat classes.
假设世纪的行为是不同的。在 DateTimeFormatter
class 中,两位数的世纪被解释为 21 世纪,因此年份 在 2000 到 2099 范围内。
java.time classes 包括 LocalDate
,用于表示没有时间和时区的仅日期值。
String input = "02/01/47";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern( "dd/MM/yy" );
LocalDate localDate = LocalDate.parse( input , formatter );
2047-01-02
顺便说一句,提示:尽可能避免使用两位数的年份。所引起的混乱和麻烦不值得节省两个字节和一点碳粉。
实际上,我发现 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);
假设您使用的是 SimpleDateFormat
:02/05/37 被解析为 02/05/1937 符合规范。至少在接下来的一年左右...
Java 的 SimpleDateFormat 必须决定您的日期应该在哪个世纪。它通过将日期调整为在创建 SimpleDateFormat 实例之前 80 年和之后 20 年内来实现。 2037 比当前日期 (2016) 早 80 年,因此它使用过去的时间。
如果您不提供世纪信息,那么它必须做出假设,并且相当合理地假设您将主要希望过去的日期,以及未来日期的一些范围,但不会太远,因为您更有可能想要更早的日期,例如出生日期等。而且人们通常能活到 80 岁左右。根据这个假设,对于任何给定的当前日期,过去的日期远远多于未来的日期。
来自 spec...
For parsing with the abbreviated year pattern ("y" or "yy"), SimpleDateFormat must interpret the abbreviated year relative to some century. It does this by adjusting dates to be within 80 years before and 20 years after the time the SimpleDateFormat instance is created. For example, using a pattern of "MM/dd/yy" and a SimpleDateFormat instance created on Jan 1, 1997, the string "01/11/12" would be interpreted as Jan 11, 2012 while the string "05/04/64" would be interpreted as May 4, 1964. During parsing, only strings consisting of exactly two digits, as defined by Character.isDigit(char), will be parsed into the default century. Any other numeric string, such as a one digit string, a three or more digit string, or a two digit string that isn't all digits (for example, "-1"), is interpreted literally. So "01/02/3" or "01/02/003" are parsed, using the same pattern, as Jan 2, 3 AD. Likewise, "01/02/-3" is parsed as Jan 2, 4 BC.
Otherwise, calendar system specific forms are applied. For both formatting and parsing, if the number of pattern letters is 4 or more, a calendar specific long form is used. Otherwise, a calendar specific short or abbreviated form is used.
因此,如果您要对此进行处理,则需要检查格式化日期是否早于今天的日期(或您选择的其他截止日期),然后将给定日期加上 100 年, 如果您希望只有未来日期或超出默认日期的不同截止日期。
其他答案正确。您需要了解 SimpleDateFormat
假设您预期世纪的行为。
您使用的是过时的 classes。新推荐的 classes 在这个问题上有不同的行为。
java.time
java.time 框架内置于 Java 8 及更高版本取代了旧的 java.util.Date 和 SimpleDateFormat classes.
假设世纪的行为是不同的。在 DateTimeFormatter
class 中,两位数的世纪被解释为 21 世纪,因此年份 在 2000 到 2099 范围内。
java.time classes 包括 LocalDate
,用于表示没有时间和时区的仅日期值。
String input = "02/01/47";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern( "dd/MM/yy" );
LocalDate localDate = LocalDate.parse( input , formatter );
2047-01-02
顺便说一句,提示:尽可能避免使用两位数的年份。所引起的混乱和麻烦不值得节省两个字节和一点碳粉。