3

I want to parse a date which only consists of date and month information, without a year. The resulting date should be set to the current year.

The input for example will be something like "11. November".

My idea was to use something like this:

DateTimeFormatter.ofPattern("EEEE dd. MMMM");

But in the resulting date the year is set to 1970 which makes sense.

Is there a way of setting the omitted year to a certain value within DateTimeFormatter?

Basil Bourque
  • 303,325
  • 100
  • 852
  • 1,154
Jonas
  • 41
  • 4
  • What about modifying the input string and adding some default year? – Tim Biegeleisen Nov 19 '18 at 16:01
  • I'd assume that if the year is missing then the current year is meant so a "constant" value wouldn't help. – Thomas Nov 19 '18 at 16:02
  • @Thomas I suspect that “constant” was an accidental poor choice of words. Fixed now. – Basil Bourque Nov 19 '18 at 18:04
  • Have you got a day of week or not? The `EEEE` in your format pattern seems to suggest you have, but it itsn’t in your example string. If you have, it could provide valuable validation, so don’t just throw it away. Another question, would you know if the date is in the past or in the future? For example, when parsing `15. December` in January, December of the previous year might be a better assumption? – Ole V.V. Nov 19 '18 at 18:29

1 Answers1

9

Parse into a MonthDay and add the year. Change the Locale as appropriate.

Parse the input string.

final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd. MMMM", Locale.UK);
final MonthDay monthDay = MonthDay.parse("11. November", formatter) ;

Apply the desired year.

final int currentYear = LocalDate.now().getYear();
final LocalDate date = monthDay.atYear(currentYear);

Worth noting, if you have something like 29th February and you add the year 2018 (not a leap year) then it will get pushed back to the 28th because the 29/02/2018 is not a valid date.

Basil Bourque
  • 303,325
  • 100
  • 852
  • 1,154
Michael
  • 41,989
  • 11
  • 82
  • 128
  • 1
    I suggest passing a specific `Locale` as well, rather than relying implicitly on the JVM’s current default JVM. The `Locale` determines the human language used in translation of name of month or day etc. The `Locale` also provides the cultural norms used in deciding issues of abbreviation, punctuation, and so on. – Basil Bourque Nov 19 '18 at 17:54
  • Another suggestion: Always specify the desired/expected time zone when calling `LocalDate::now` rather than relying implicitly on the current default time zone. – Basil Bourque Nov 19 '18 at 18:08
  • While Ole V.V. posted a [correct Answer](https://stackoverflow.com/a/44470949/642706) on [the original](https://stackoverflow.com/q/8523886/642706) of this duplicate Question, I suggest you post this Answer there too. Your approach here is different, useful, and educative. – Basil Bourque Nov 19 '18 at 19:00