views:

185

answers:

4

Is there a way to force Joda time to parse dates only when they contain four digit years? For example:

  • 2009-11-11 - should parse
  • 09-11-11 - should not parse

Tried the following code:

DateTimeFormatterBuilder builder = new DateTimeFormatterBuilder();
DateTimeFormatter formatter = builder.appendYear(4, 4).appendLiteral('-').appendMonthOfYear(1).appendLiteral('-').appendDayOfMonth(1).toFormatter();
formatter.parseDateTime("09-11-11");

Parses into 0009-11-11. Apparently minDigits in the method appendYear are only used for formatting when printing out the date.
The result is the same if I use appendYearOfEra(). If I use appendYearOfCentury(), it parses the year into 1909 instead.

We are implementing a general data parser, which will recognize various types of inputs. Also the example is a shortened form of the real deal (for simplicity). Real life scenarios parses dates which can have weekdays, months as words, time, zone and different characters separating month, day and year. Therefore, writing a RegEx or checking the content/length of the string can prove rather difficult.

Some real examples could look like this:

  • 2009-11-11
  • Wednesday 2009-11-11T15:00:00
  • 2009/11/11 15:00
  • and many more...
+1  A: 

You can build extremely specific parsers and formatters using DateTimeFormatterBuilder. There's generally no need to use this class directly, since most common formats are more easily available elsewhere in the API, but this is the builder class they all use under the covers.

skaffman
I edited the post with results of your suggestion. Unfortunately I can't get it work. Thanks!
Emilis Panovas
Hmm, interesting, I wouldn't have expected that. I suggest the joda-time mailing list, the author(s) hang about on there.
skaffman
A: 

You can check the length of the date string.

Peter Lawrey
A: 

What do you want to get from a user who enters '0001-01-01' as the date (that is, they entered 4 digits for the year, but the first three were zeroes)? What about '0999-12-31'? And '999-12-31'? And what about '10000-01-01' - the infamous Y10K1 problem?

  • If that is a legitimate value, then you are stuck with discovering the length of what the user typed as the year portion of the date (probably after any other parsing has been done), and making sure it is at least (or is it exactly?) four digits.

  • If that is not a legitimate value, then you are stuck with checking the year value after the date is parsed.

  • Or you can take the code and modify it so it includes your preferred definition of valid year.


1 I do not plan to start working on fixing the Y10K problem before 5000-01-02.

Jonathan Leffler
I'm looking for a way to limit it to four digits exactly, so 0999 would be treated as year 999 and 999 would not parse. Also the Y10K is not an issue...well not yet at least. Anyway, it seems like the only solution is to check the string before parsing it.
Emilis Panovas
+3  A: 

DateTimeFormatterBuilder.appendFixedDecimal() may well do what you need.

Alternatively, you could implement the DateTimeParser interface to create whatever parser you want and pass that into the DateTimeFormatterBuilder.

JodaStephen
I was blind! Thank you so much. By the way the method is called appendFixedDecimal().
Emilis Panovas