Subtract months from date

Opposite of adding months to a java date, this example will demonstrate how to substract a number of months from a date using java's Calendar.add, java 8 date time api, joda’s DateTime.minusMonths and apache commons DateUtils.addMonths. February 6, 2011, the date used in the examples below, was super bowl XLV between Pittsburgh Steelers and Green Bay Packers.

Straight up Java

@Test
public void subtract_months_from_date_in_java () {

    Calendar superBowlXLV = Calendar.getInstance();
    superBowlXLV.set(2011, 1, 6, 0, 0);

    Calendar championshipWeekend = Calendar.getInstance();
    championshipWeekend.setTimeInMillis(superBowlXLV.getTimeInMillis());
    championshipWeekend.add(Calendar.MONTH, -1);

    SimpleDateFormat dateFormatter = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss z");

    logger.info(dateFormatter.format(superBowlXLV.getTime()));
    logger.info(dateFormatter.format(championshipWeekend.getTime()));

    assertTrue(championshipWeekend.before(superBowlXLV));
}

Output

02/06/2011 00:00:18 CST
01/06/2011 00:00:18 CST

Java 8 Date and Time API

Java 8 LocalDateTime.minusMonths will return a copy of the LocalDateTime with the specified number of months subtracted.

@Test
public void subtract_months_from_date_in_java8() {

    LocalDateTime superBowlXLV = LocalDateTime.of(2011, Month.FEBRUARY, 6,
            0, 0);
    LocalDateTime championshipWeekend = superBowlXLV.minusMonths(1);

    java.time.format.DateTimeFormatter formatter = java.time.format.DateTimeFormatter
            .ofPattern("MM/dd/yyyy HH:mm:ss");

    logger.info(superBowlXLV.format(formatter));
    logger.info(championshipWeekend.format(formatter));

    assertTrue(championshipWeekend.isBefore(superBowlXLV));
}

Output

02/06/2011 00:00:00
01/06/2011 00:00:00

Joda Time

Joda DateTime.minusMonths will return a copy the DateTime minus the specified number of months.

@Test
public void subtract_months_from_date_in_java_joda () {

    DateTime superBowlXLV = new DateTime(2011, 2, 6, 0, 0, 0, 0);
    DateTime championshipWeekend = superBowlXLV.minusMonths(1);

    DateTimeFormatter fmt = DateTimeFormat.forPattern("MM/dd/yyyy HH:mm:ss z");

    logger.info(superBowlXLV.toString(fmt));
    logger.info(championshipWeekend.toString(fmt));

    assertTrue(championshipWeekend.isBefore(superBowlXLV));
}

Output

02/06/2011 00:00:00 CST
01/06/2011 00:00:00 CST

Apache Commons

Apache commons DateUtils.addMonths will adds a number of months, in this case a negative number of months, to the date returning a new object.

@Test
public void subtract_months_from_date_in_java_apachecommons () {

    Calendar superBowlXLV = Calendar.getInstance();
    superBowlXLV.set(2011, 1, 6, 0, 0);

    Date championshipWeekend = DateUtils.addMonths(superBowlXLV.getTime(), -1);

    SimpleDateFormat dateFormatter = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss z");

    logger.info(dateFormatter.format(superBowlXLV.getTime()));
    logger.info(dateFormatter.format(championshipWeekend));

    assertTrue(championshipWeekend.before(superBowlXLV.getTime()));
}

Output

02/06/2011 00:00:52 CST
01/06/2011 00:00:52 CST