16

I have the following formatter:

DateTimeFormatter formatter = new DateTimeFormatterBuilder()
        .appendPattern("yyyyMM")
        .parseDefaulting(ChronoField.SECOND_OF_MINUTE, 0)
        .parseDefaulting(ChronoField.MINUTE_OF_HOUR, 0)
        .parseDefaulting(ChronoField.HOUR_OF_DAY, 0)
        .parseDefaulting(ChronoField.DAY_OF_MONTH, 1)
        .parseDefaulting(ChronoField.MONTH_OF_YEAR, 1)
        .parseDefaulting(ChronoField.YEAR, ZonedDateTime.now().getYear())
        .toFormatter()
        .withZone(ZoneId.systemDefault());

I try to parse the string "201505"

System.out.println(ZonedDateTime.parse("201505", formatter));

and it throws an exception:

Caused by: java.time.DateTimeException: Conflict found: Year 2016 differs from Year 2015

It works if I comment out the setting of default value for YEAR.

As far as I understood the documentation, it should only try to replace the default value if there is no value parsed. Seems like this works for month as I have different month than the default one parsed. However it doesn't work for year.

Am I using it wrong could someone tell me if there is a different way to define default values for fields that might not be present in a pattern?

assylias
  • 321,522
  • 82
  • 660
  • 783
  • 2
    Why do you want to parse input in format "yyyyMM" to `ZonedDateTime` and not to `YearMonth`? – Meno Hochschild Jul 11 '16 at 15:42
  • 2
    I have a code that parses different formats there are like 40-50 different patterns that the formatter receives. I wanted to use one general formatter for parsing that always result a ZonedDateTime. That's just one of the cases I have. – Ivelina Georgieva Jul 12 '16 at 17:32
  • Oh really 40-50 patterns? Do you also have different locales, too? What about performance? It must be bad due to internal exception throw/catch. Can you please report your speed experience? – Meno Hochschild Jul 12 '16 at 20:17
  • I'm sorry I wasn't clear. They are not parsed at the same time. I just have common code that parses and then does some additional things with the object. With Joda time it worked fine with DateTime but with new java api you need to have different objects.. that's what I don't want for now since I want to port to Java datetime without changing too many things. That's why I decided ZonedDateTime would work for me. – Ivelina Georgieva Jul 13 '16 at 21:05
  • Thanks for feedback. So I understand this decision is just a first migration step in order to avoid too much refactoring at the begin. Nevertheless you should consider further refactoring in medium term because the code readability and maintenance suffers from using `ZonedDateTime` at all places where other types are easier to understand and more appropriate. – Meno Hochschild Jul 13 '16 at 21:41

1 Answers1

15

The problem is that the pattern letter "y" refers to ChronoField.YEAR_OF_ERA, not ChronoField.YEAR. Simply change the last parseDefaulting line:

.parseDefaulting(ChronoField.YEAR_OF_ERA, ZonedDateTime.now().getYear())

and it should work.

JodaStephen
  • 60,927
  • 15
  • 95
  • 117