具有2年日期的java SimpleDateFormat问题
我试图理解两件事:
- 为什么下面的代码不抛出异常(因为
SimpleDateFormat
并不宽松) - 它没有抛出异常,但为什么它将年份解析为0013(而不是+80:-20年后的今天规则)
这是密码
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
public class TestDate {
public static void main(String[] args) throws Exception {
SimpleDateFormat format = new SimpleDateFormat("dd/MM/yyyy");
format.setLenient(false);
Date date = format.parse("01/01/13"); // Since this only has a 2 digit year, I would expect an exception to be thrown
System.out.println(date); // Prints Sun Jan 01 00:00:00 GMT 13
Calendar cal = Calendar.getInstance();
cal.setTime(date);
System.out.println(cal.get(Calendar.YEAR)); // Prints 13
}
}
如果有区别的话,我正在Ubuntu上使用java 1.6.0_38-b05
# 1 楼答案
根据JDK1.6的SimpleDateFormat javadoc
查看执行该工作的方法的源代码
SimpleDateFormat.parse(String, ParsePosition)
可以证实这一点。如果模式没有分隔符,比如“yyyyMMdd”,则变量obeyCount
为true,否则为false。根据您的模式,解析器查找由2个分隔符分隔的3个数字,而不关心每个位置的位数您的问题的答案如下:
# 2 楼答案
SimpleDataFormat API:
对于解析,如果模式字母的数量超过2,则不管数字的数量如何,都会按字面解释年份。因此,使用模式“MM/dd/yyyy”,“01/11/12”解析为公元12年1月11日
至于lenient,当设置为false时,parse会抛出无效日期的异常,例如01/32/12,而在lenient模式下,该日期将被视为02/01/12。SimpleDataFormat在内部使用日历,有关宽大处理的详细信息可以在日历API中找到
# 3 楼答案
爪哇。时间
使用java。时间、现代Java日期和时间API,以及您所期望的例外情况:
结果:
如果向右滚动,您将看到异常消息提到“无法在索引6处解析”。字符串中的索引6是两位数年份的位置,预计为四位数
当这个问题在近7年前被提出时,使用
SimpleDateFormat
和Date
是可以接受的。它们的设计总是很糟糕,而且在提出问题7个月后就出现了替换品,因此它们现在被认为早已过时。我强烈推荐使用java。而是时间链接
解释如何使用java。时间到了
# 4 楼答案
问题1这是Why Does Java's SimpleDateFormat parse this的部分重复。关于这个问题的第二个答案很好地回答了这个问题。关键在于:
Number:对于解析,除非需要分隔两个相邻字段,否则将忽略模式字母的数量。 年份:在解析过程中,只有正好由两个数字组成的字符串[…]将被解析为默认世纪。任何其他数字字符串,例如一位字符串、三位或更多位字符串,或不是所有数字的两位字符串(例如“-1”),都会按字面解释。所以“01/02/3”或“01/02/003”被解析,使用相同的模式
问题2仔细查看:输入格式与传递给函数的格式不同
new SimpleDateFormat("dd/MM/yyyy");
与
format.parse("01/01/13");
要么解析为
01/01/2013
,要么使用'dd/MM/yy'
的日期