4

The following test fails: a '86 birthday is formated as 2068. How can I format is as 1986?

    @Test
    public void testBirthday() {
        assertEquals("1986-08-07", java.time.LocalDate.parse("070886", 
             java.time.format.DateTimeFormatter.ofPattern("ddMMyy")));
    }

Fails with:

java.lang.AssertionError: expected:<1986-08-07> but was:<2086-08-07>

This is much different to org.joda.time library which would correctly assume 19' here.

/Sidenote: regarding the marked answers in the "duplicate" questions, I don't think this is a duplicate!

membersound
  • 81,582
  • 193
  • 585
  • 1,120
  • 1
    The facetious answer is to use `org.joda.time`. – Bathsheba Jul 13 '16 at 14:15
  • 3
    No it's not. `joda` is actually "deprecated" and no longer developed. At least the authors themselves suggest switching to java8 `java.time` nowadays. – membersound Jul 13 '16 at 14:16
  • 1
    Just to note, this is the documented behaviour: "If the count of letters is two, then a reduced two digit form is used. For printing, this outputs the rightmost two digits. For parsing, this will parse using the base value of 2000, resulting in a year within the range 2000 to 2099 inclusive." Unfortunately it doesn't say how to *change* that behaviour. You might be able to specify a separate ResolverField, but it feels a little contrived. You may well find it simpler just to "fix" the string manually to use a four-digit year. – Jon Skeet Jul 13 '16 at 14:17
  • Write your own parse method. How should `java.time.LocalDate.parse` know what you expect? "070886" contains no information about the century. – MrSmith42 Jul 13 '16 at 14:17
  • Since you are using a parse function, you could provide a pattern `ddMMyyyy` and a time of `07081986`. – tobi6 Jul 13 '16 at 14:17
  • I stand corrected. Have a question upvote. Back in my box. – Bathsheba Jul 13 '16 at 14:21
  • If your format pattern is variable (style-based, not known at compile-time) then [this post](http://stackoverflow.com/questions/32782645/parsing-2-digit-years-setting-the-pivot-date-with-an-unknown-date-pattern) might help you. – Meno Hochschild Jul 13 '16 at 14:32

2 Answers2

2

The base year can be controlled using DateTimeFormatterBuilder.appendValueReduced().

This code would parse with a base date of 1900 rather than 2000:

DateTimeFormatter f = new DateTimeFormatterBuilder()
  .appendPattern("ddMM")
  .appendValueReduced(ChronoField.YEAR, 2, 2, 1900)
  .toFormatter();
LocalDate date = LocalDate.parse("070886", f);
JodaStephen
  • 60,927
  • 15
  • 95
  • 117
-1

Java 8's LocalDate class uses 2000+ for the year by default. In order to parse a yy format for 1900 and up, you'll need to reduce the time yourself.

Of course, even if you check the date against the current year and subtract 100 years if its after today, this fix won't work for people over 100 years old.

You can also use a yyyy format. Or just make use of a Date object instead, and convert it to a LocalDate if you wish.

Zircon
  • 4,677
  • 15
  • 32