开发者

SimpleDateFormat fails to reject input missing century on the year of the input, despite "yyyy" in the formatting pattern

I have a SimpleDateFormat with the pattern yyyy-M-d", and the following scenario:

String str = "02-03-04";        
SimpleDateFormat f = new SimpleDateFormat("yyyy开发者_开发技巧-M-d");
f.setLenient(false);
System.out.println(f.parse(str));

The output is Sat Mar 04 00:00:00 EST 2

My goal was to only catch dates in the format like 2004-02-03 and to ignore 02-03-04. I thought the yyyy in the pattern would require a 4 digit year, but clearly this is not the case. Can anyone explain why this is not throwing a parse exception? I would like it to...


Well, I can explain it from the docs:

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.

It's possible that Joda Time would be stricter - and it's a better API in general, IMO...

You could always throw an exception if the year is less than 1000 after parsing...


tl;dr

Using java.time, that input with that formatting pattern fails, just as you expected.

LocalDate
.parse(
    "02-03-04" ,
    DateTimeFormatter.ofPattern ( "uuuu-M-d" )
)

…throws java.time.format.DateTimeParseException

java.time

The classes you were using are now supplanted by the modern java.time classes defined in JSR 310 and built into Java 8 and later.

The LocalDate class represents a date-only value without time-of-day and without time zone or offset-from-UTC.

Define a custom formatting pattern as you asked. Use the DateTimeFormatter class.

DateTimeFormatter f = DateTimeFormatter.ofPattern ( "uuuu-M-d" );

Try to parse your input.

String input = "02-03-04";
LocalDate localDate = LocalDate.parse ( input , f );

We encounter a DateTimeParseException, failing on the missing century of the year of the input. Just as you expected.

Exception in thread "main" java.time.format.DateTimeParseException: Text '02-03-04' could not be parsed at index 0


About java.time

The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.

To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.

The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.

You may exchange java.time objects directly with your database. Use a JDBC driver compliant with JDBC 4.2 or later. No need for strings, no need for java.sql.* classes.

Where to obtain the java.time classes?

  • Java SE 8, Java SE 9, Java SE 10, Java SE 11, and later - Part of the standard Java API with a bundled implementation.
    • Java 9 adds some minor features and fixes.
  • Java SE 6 and Java SE 7
    • Most of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
  • Android
    • Later versions of Android bundle implementations of the java.time classes.
    • For earlier Android (<26), the ThreeTenABP project adapts ThreeTen-Backport (mentioned above). See How to use ThreeTenABP….

The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜