我试图理解两件事:
SimpleDateFormat
不宽松)这是代码
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
答案 0 :(得分:2)
问题1。这是Why Does Java's SimpleDateFormat parse this的部分副本。问题的第二个答案很好地回答了这个问题。关键在于:
数字:对于解析,忽略模式字母的数量,除非需要分隔两个相邻的字段。 年份:在解析过程中,只有包含正好两位数字的字符串才会被解析为默认世纪。字面上解释任何其他数字字符串,例如一位数字符串,三位或更多位数字符串,或不是所有数字的两位数字符串(例如,“ - 1”)。所以使用相同的模式解析“01/02/3”或“01/02/003”
问题2。仔细观察:您的输入格式与传递给该功能的格式不同。
new SimpleDateFormat("dd/MM/yyyy");
VS
format.parse("01/01/13");
解析为01/01/2013
或使用日期'dd/MM/yy'
。
答案 1 :(得分:2)
SimpleDateFormat API:
对于解析,如果模式字母的数量大于2,则无论数字位数如何,都按字面解释年份。所以使用模式" MM / dd / yyyy"," 01/11/12"解析到1月11日,12 A.D。
对于lenient,当它被设置为false parse时会引发无效日期的异常,例如01/32/12,而在宽松模式下,此日期被视为02/01/12。 SimpleDateFormat在内部使用Calendar,可以在Calendar API中找到有关宽大的详细信息。
答案 2 :(得分:1)
根据JDK 1.6的SimpleDateFormat javadoc,
对于解析,除非是,否则忽略模式字母的数量 需要将两个相邻的区域分开。
查看完成工作的方法的源代码SimpleDateFormat.parse(String, ParsePosition)
,确认了这一点。如果模式没有分隔符(如“yyyyMMdd”),则变量obeyCount
为true,否则为false。使用您的模式,解析器会查找由2个分隔符分隔的3个数字,而不关心每个位置的位数。
您的问题的答案:
Lenient
不是使用分隔符的因素。SimpleDateFormat.set2DigitYearStart
那么为什么代码会做你没告诉它做的事情呢?答案 3 :(得分:1)
使用java.time(现代的Java日期和时间API),您所期望的异常肯定会发生:
DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("dd/MM/yyyy");
String strToParse = "01/01/13";
LocalDate date = LocalDate.parse(strToParse, dateFormatter);
结果:
Exception in thread "main" java.time.format.DateTimeParseException: Text '01/01/13' could not be parsed at index 6 at java.base/java.time.format.DateTimeFormatter.parseResolved0(DateTimeFormatter.java:2046) at java.base/java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:1948) at java.base/java.time.LocalDate.parse(LocalDate.java:428)
如果向右滚动,您将看到异常消息中提到“无法在索引6处解析”。字符串中的索引6是两位数字所在的年份所在的位置,预期是四位数。
将近7年前问这个问题时,可以使用SimpleDateFormat
和Date
。它们的设计总是很差,在被问到问题7个月后就更换了它们,因此现在认为它们已经过时了。我热烈建议改用java.time。
Oracle tutorial: Date Time解释了如何使用java.time。