问题
I have this code:
DateFormat dateFormat = new SimpleDateFormat("MM/dd/yyyy");
dateFormat.setLenient(false);
Date date = dateFormat.parse("10/20/20128");
and I would expect the dateFormat.parse call to throw ParseException since the year I'm providing is 5 characters long instead of 4 like in the format I defined. But for some reason even with the lenient set to false this call returns a Date object of 10/20/20128.
Why is that? It doesn't make much sense to me. Is there another setting to make it even more strict?
回答1:
20128 is a valid year and Java hopes the world to live that long I guess.
if the number of pattern letters is more than 2, the year is interpreted literally, regardless of the number of digits.
Reference.
If you want to validate if a date is in limit, you can define one and check-
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");
}
回答2:
See the javadoc
Year: If the formatter's Calendar is the Gregorian calendar, the following rules are applied.
- For formatting, if the number of pattern letters is 2, the year is truncated to 2 digits; otherwise it is interpreted as a number.
- For parsing, if the number of pattern letters is more than 2, the year is interpreted literally, regardless of the number of digits. So using the pattern "MM/dd/yyyy", "01/11/12" parses to Jan 11, 12 A.D.
- 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.
Therefore, it will read all the characters that come after the last /
as the year.
回答3:
See java.text.SimpleDateFormat
API, pattern letter y
: For parsing, if the number of pattern letters is more than 2, the year is interpreted literally, regardless of the number of digits.
回答4:
Using SimpleDateFormat in java, you can achieve a number of human readable formats. Consider this code snippet:
Date curDate = new Date();
SimpleDateFormat format = new SimpleDateFormat("yyyy/MM/dd");
String DateToStr = format.format(curDate);
System.out.println(DateToStr);
format = new SimpleDateFormat("dd-M-yyyy hh:mm:ss");
DateToStr = format.format(curDate);
System.out.println(DateToStr);
format = new SimpleDateFormat("dd MMMM yyyy zzzz", Locale.ENGLISH);
DateToStr = format.format(curDate);
System.out.println(DateToStr);
format = new SimpleDateFormat("E, dd MMM yyyy HH:mm:ss z");
DateToStr = format.format(curDate);
System.out.println(DateToStr);
Look at the various outputs generated by the various formats:
2014/05/11
11-5-2014 11:11:51
11 May 2014 Eastern European Summer Time
Sun, 11 May 2014 23:11:51 EEST
Feel free to modify the format string and you might get the desired result.
来源:https://stackoverflow.com/questions/18534343/why-simpledateformatmm-dd-yyyy-parses-date-to-10-20-20128