1

I am using the SimpleDateFormatter class to convert a string into a date. I have the following code which works for Feb 27, 2020:

SimpleDateFormat FORMATTER = new SimpleDateFormat("ddMM"); //always current year
Date TODAY = FORMATTER.parse("2702");
System.out.println(TODAY);

This resolves to the following date:

Fri Feb 27 00:00:00 UTC 1970

However, when I try the same for Feb 29, 2020 (a leap year), I get an error:

Code:

SimpleDateFormat FORMATTER = new SimpleDateFormat("ddMM"); //always current year
Date TODAY = FORMATTER.parse("2902");
System.out.println(TODAY);

Output:

Sun Mar 01 00:00:00 UTC 1970

Can someone please suggest a way so that I can take into account leap years as well, using this date format?

Thank you.

Shiv
  • 23
  • 2
  • If it isn't a leap year when you run the program, and you pass it Feb 29, what year do you expect the resulting date to come out to? – Louis Wasserman Mar 02 '20 at 21:44
  • 1
    `1970` wasn't a leap year :/ – MadProgrammer Mar 02 '20 at 21:51
  • 1
    That's a good edge case, I think in such a condition, the result should be an exception. – Shiv Mar 02 '20 at 21:51
  • 3
    As a preference, I would recommend making use of the newer `java.time.*` API instead. In which case, you should specify the anchor year, [for example](https://stackoverflow.com/questions/41358069/parsing-a-year-string-to-a-localdate-with-java8) – MadProgrammer Mar 02 '20 at 21:55
  • I recommend you don’t use `SimpleDateFormat` and `Date`. Those classes are poorly designed and long outdated, the former in particular notoriously troublesome. Instead use `LocalDate` and `DateTimeFormatter`, both from [java.time, the modern Java date and time API](https://docs.oracle.com/javase/tutorial/datetime/). You may also consider `DateTimeFormatterBuilder` or `MonthDay` from java.time. – Ole V.V. Mar 03 '20 at 03:17
  • Does this answer your question? [How do I simply parse a date without a year specified?](https://stackoverflow.com/questions/8523886/how-do-i-simply-parse-a-date-without-a-year-specified) – Ole V.V. Mar 03 '20 at 03:22

1 Answers1

1

You should use the Java 8 Time API, because it supports specifying a default year.

public static Date dayMonthToDate(String dayMonth) {
    DateTimeFormatter FORMATTER = new DateTimeFormatterBuilder()
            .appendPattern("ddMM")
            .parseDefaulting(ChronoField.YEAR, Year.now().getValue())
            .toFormatter();

    LocalDate localDate = LocalDate.parse(dayMonth, FORMATTER);
    Instant instant = localDate.atStartOfDay(ZoneId.systemDefault()).toInstant();
    return Date.from(instant);
}

Test

public static void main(String[] args) {
    TimeZone.setDefault(TimeZone.getTimeZone("UTC"));

    System.out.println(dayMonthToDate("2702"));
    System.out.println(dayMonthToDate("2902"));
}

Output

Thu Feb 27 00:00:00 UTC 2020
Sat Feb 29 00:00:00 UTC 2020
Andreas
  • 154,647
  • 11
  • 152
  • 247