-1

I have this wired

   public static boolean isFirstDayOfMonth(String format, String value) {
    SimpleDateFormat sdf = new SimpleDateFormat(format);
    Date date = null;
    try {
        date = sdf.parse(value);
    } catch (ParseException e) {
        e.printStackTrace();
    }
    Calendar calendar = Calendar.getInstance();
    calendar.setTime(date);
    int dayOfMonth = calendar.get(Calendar.DAY_OF_MONTH);
    return dayOfMonth == 1;
   }

Test and return true:

    boolean actual = CommonUtil.isFirstDayOfMonth("yyyy-MM-dd", "2021-02-29");
    assertTrue(actual);

The I found out SimpleDateFormat convert the date into 1st of March 2021, although there is not 29th in February in 2021. If I pass in 2021-02-30, which is invalid, but it return correct result.

Alvin
  • 8,219
  • 25
  • 96
  • 177
  • 2
    I've not looked at your actually problem, but, I wouldn't be using `SimpleDateFormat` or any of the related `Date` classes any more and instead would be making using the `java.time` APIs instead – MadProgrammer Jun 19 '21 at 00:46
  • 2
    You are using *terrible* date-time classes that were years ago supplanted by the *java.time* classes defined in JSR 310. – Basil Bourque Jun 19 '21 at 00:47
  • 2
    Call `sdf.setLenient(false);` – Andreas Jun 19 '21 at 00:55
  • In addition to using java.time you should also respect the *single responsibility principle* better. Create one method for interpreting your string into a `LocalDate` and another for determining whether that `LocalDate` falls on the first of a month. – Ole V.V. Jun 19 '21 at 04:30

1 Answers1

2

tl;dr

java.time.LocalDate.parse( "2021-02-29" )
…
catch ( DateTimeParseException e )  // Thrown for invalid inputs

java.time

You are using terrible date-time classes that were years ago supplanted by the java.time classes defined in JSR 310.

By default, the java.time.LocalDate class refuses to parse invalid inputs. Trap for the parse exception.

    try {
        LocalDate ld = LocalDate.parse( "2021-02-29" ) ;
        System.out.println( ld ) ;
    } catch ( DateTimeParseException e ) {
        // … handle invalid input
        System.out.println( "Faulty input" ) ;
    }

See this code run live at IdeOne.com.


About java.time

The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.

To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.

The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.

You may exchange java.time objects directly with your database. Use a JDBC driver compliant with JDBC 4.2 or later. No need for strings, no need for java.sql.* classes. Hibernate 5 & JPA 2.2 support java.time.

Where to obtain the java.time classes?

Basil Bourque
  • 303,325
  • 100
  • 852
  • 1,154