How to subtract X days from a date using Java calendar?

Viewed 291635

Anyone know a simple way using Java calendar to subtract X days from a date?

I have not been able to find any function which allows me to directly subtract X days from a date in Java. Can someone point me to the right direction?

11 Answers

Taken from the docs here:

Adds or subtracts the specified amount of time to the given calendar field, based on the calendar's rules. For example, to subtract 5 days from the current time of the calendar, you can achieve it by calling:

Calendar calendar = Calendar.getInstance(); // this would default to now
calendar.add(Calendar.DAY_OF_MONTH, -5).

You could use the add method and pass it a negative number. However, you could also write a simpler method that doesn't use the Calendar class such as the following

public static void addDays(Date d, int days)
{
    d.setTime( d.getTime() + (long)days*1000*60*60*24 );
}

This gets the timestamp value of the date (milliseconds since the epoch) and adds the proper number of milliseconds. You could pass a negative integer for the days parameter to do subtraction. This would be simpler than the "proper" calendar solution:

public static void addDays(Date d, int days)
{
    Calendar c = Calendar.getInstance();
    c.setTime(d);
    c.add(Calendar.DATE, days);
    d.setTime( c.getTime().getTime() );
}

Note that both of these solutions change the Date object passed as a parameter rather than returning a completely new Date. Either function could be easily changed to do it the other way if desired.

Anson's answer will work fine for the simple case, but if you're going to do any more complex date calculations I'd recommend checking out Joda Time. It will make your life much easier.

FYI in Joda Time you could do

DateTime dt = new DateTime();
DateTime fiveDaysEarlier = dt.minusDays(5);

I faced the same challenge where I needed to go back by 1 day (should be able to roll back by one even if previous day falls into previous year or months).

I did following, basically subtracted by 24 hours for 1 day. someDateInGregorianCalendar.add(Calendar.HOUR, -24);

Alternatively, I could also do

GregorianCalendar cal = new GregorianCalendar();
    cal.set(Calendar.YEAR, 2021);
    cal.set(Calendar.MONTH, 0);
    cal.set(Calendar.DATE, 1);
    System.out.println("Original: " + cal.getTime());
    cal.add(Calendar.DATE, -1);
    System.out.println("After adding DATE: " + cal.getTime());

OUTPUT:

Original: Fri Jan 01 15:08:33 CET 2021
After adding DATE: Thu Dec 31 15:08:33 CET 2020

I believe a clean and nice way to perform subtraction or addition of any time unit (months, days, hours, minutes, seconds, ...) can be achieved using the java.time.Instant class.

Example for subtracting 5 days from the current time and getting the result as Date:

new Date(Instant.now().minus(5, ChronoUnit.DAYS).toEpochMilli());

Another example for subtracting 1 hour and adding 15 minutes:

Date.from(Instant.now().minus(Duration.ofHours(1)).plus(Duration.ofMinutes(15)));

If you need more accuracy, Instance measures up to nanoseconds. Methods manipulating nanosecond part:

minusNano()
plusNano()
getNano()

Also, keep in mind, that Date is not as accurate as Instant. My advice is to stay within the Instant class, when possible.

Related