75

Possible Duplicate:
Calculating the Difference Between Two Java Date Instances

In Java, I want to calculate the number of days between two dates.

In my database they are stored as a DATE datatype, but in my code they are strings.

I want to calculate the no of days between those two strings.

Community
  • 1
  • 1
sgrgmngt
  • 907
  • 3
  • 12
  • 15

10 Answers10

139

Note: this answer was written in 2011. I would recommend using java.time now instead of Joda Time.

Well to start with, you should only deal with them as strings when you have to. Most of the time you should work with them in a data type which actually describes the data you're working with.

I would recommend that you use Joda Time, which is a much better API than Date/Calendar. It sounds like you should use the LocalDate type in this case. You can then use:

int days = Days.daysBetween(date1, date2).getDays();
Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • 2
    Seems like this method is exclusive and not inclusive, so might want to add 1 to the result (or add **25** (and not 24) hours to `date2`) to make it inclusive. – Alaa M. Dec 25 '16 at 20:59
  • @AlaaM.: Well, *if* you want to make it inclusive. If I were asked the number of days between December 24th and December 25th, I'd say 1, not 2... (And the OP seems happy enough.) – Jon Skeet Dec 25 '16 at 21:19
  • 1
    Yeah that's why I said *might want*. In my case I needed to display "remaining days til expiration". So in my opinion this case should be inclusive – Alaa M. Dec 25 '16 at 21:22
  • Dont use Joda time anymore. Since Java 8, use the JDK own ones, such as java.time. – Miyagi Mar 31 '22 at 06:20
  • 1
    @Miyagi: I agree, but I'm not going to go over every answer I've posted over the last 13+ years every time technology changes. I'll edit this now, but generally I don't think it's worth commenting on posts like that. – Jon Skeet Mar 31 '22 at 11:55
  • @JonSkeet What?? You dont go through all your comments 13 years back, every day?... :-) It was a great answer, but has now been outdated. Nothing wrong. But it shouldn't recommend things that are not valid anymore. I guess I should have just edited the answer myself.... – Miyagi Apr 15 '22 at 10:45
  • this is a great example of why duplicate questions aren't necessarily a bad thing... this answer is stupidly outdated. `ChronoUnit` does the exact same thing. – Krusty the Clown Aug 10 '23 at 15:42
67

Java 8 and later: ChronoUnit.between

Use instances of ChronoUnit to calculate amount of time in different units (days,months, seconds).

For Example:

ChronoUnit.DAYS.between(startDate,endDate)
Basil Bourque
  • 303,325
  • 100
  • 852
  • 1,154
javaLearner
  • 963
  • 8
  • 5
  • 2
    Says I need to use Temporal not Date any ideas? – JGleason Sep 12 '18 at 13:27
  • 7
    `Instant now = date1.toInstant();` – gene b. Nov 05 '18 at 16:50
  • 2
    Recently I found a problem with this method: there was a change from winter to summer time between `startDate` and `endDate`. As both of them had their time at `00:00:00`, the conversion of `endDate` to `Instant` produced a result one hour before, so the days between were one less than the actual result. – Oscar Pérez Jul 10 '19 at 12:01
49

try this code

     Calendar cal1 = new GregorianCalendar();
     Calendar cal2 = new GregorianCalendar();

     SimpleDateFormat sdf = new SimpleDateFormat("ddMMyyyy");

     Date date = sdf.parse("your first date");
     cal1.setTime(date)
     date = sdf.parse("your second date");
     cal2.setTime(date);

    //cal1.set(2008, 8, 1); 
     //cal2.set(2008, 9, 31);
     System.out.println("Days= "+daysBetween(cal1.getTime(),cal2.getTime()));

this function

     public int daysBetween(Date d1, Date d2){
             return (int)( (d2.getTime() - d1.getTime()) / (1000 * 60 * 60 * 24));
     }
Pratik
  • 30,639
  • 18
  • 84
  • 159
  • 3
    how will this method will handle the daylight saving change? – eldjon Sep 07 '16 at 12:15
  • 1
    This formula is good but it will less 1 day. For example, d1 = 2nd January 2016 and d2 = 1st January 2016, it will give you 1 day instead of 2 days. – stanicmail Oct 06 '16 at 09:39
  • 13
    @stanicmail But there WAS only ONE day between Jan 1 and Jan 2, 2016! Unless you had drunk too much on d0 = 31st December 2015, of course. ;-) – tomorrow May 23 '17 at 12:27
  • FYI, these terrible date-time classes were supplanted years ago by the modern *java.time* classes. So this Answer is now obsolete. See the [other Answer](https://stackoverflow.com/a/24163958/642706) for a modern solution. – Basil Bourque Dec 07 '20 at 07:03
27

I know this thread is two years old now, I still don't see a correct answer here.

Unless you want to use Joda or have Java 8 and if you need to subract dates influenced by daylight saving.

So I have written my own solution. The important aspect is that it only works if you really only care about dates because it's necessary to discard the time information, so if you want something like 25.06.2014 - 01.01.2010 = 1636, this should work regardless of the DST:

private static SimpleDateFormat simpleDateFormat = new SimpleDateFormat("dd.MM.yyyy");

public static long getDayCount(String start, String end) {
  long diff = -1;
  try {
    Date dateStart = simpleDateFormat.parse(start);
    Date dateEnd = simpleDateFormat.parse(end);

    //time is always 00:00:00, so rounding should help to ignore the missing hour when going from winter to summer time, as well as the extra hour in the other direction
    diff = Math.round((dateEnd.getTime() - dateStart.getTime()) / (double) 86400000);
  } catch (Exception e) {
    //handle the exception according to your own situation
  }
  return diff;
}

As the time is always 00:00:00, using double and then Math.round() should help to ignore the missing 3600000 ms (1 hour) when going from winter to summer time, as well as the extra hour if going from summer to winter.

This is a small JUnit4 test I use to prove it:

@Test
public void testGetDayCount() {
  String startDateStr = "01.01.2010";
  GregorianCalendar gc = new GregorianCalendar(locale);
  try {
    gc.setTime(simpleDateFormat.parse(startDateStr));
  } catch (Exception e) {
  }

  for (long i = 0; i < 10000; i++) {
    String dateStr = simpleDateFormat.format(gc.getTime());
    long dayCount = getDayCount(startDateStr, dateStr);
    assertEquals("dayCount must be equal to the loop index i: ", i, dayCount);
    gc.add(GregorianCalendar.DAY_OF_YEAR, 1);
  }
}

... or if you want to see what it does 'life', replace the assertion with just:

System.out.println("i: " + i + " | " + dayCount + " - getDayCount(" + startDateStr + ", " + dateStr + ")");

... and this is what the output should look like:

  i: 0 | 0  - getDayCount(01.01.2010, 01.01.2010)
  i: 1 | 1  - getDayCount(01.01.2010, 02.01.2010)
  i: 2 | 2  - getDayCount(01.01.2010, 03.01.2010)
  i: 3 | 3  - getDayCount(01.01.2010, 04.01.2010)
  ...
  i: 1636 | 1636  - getDayCount(01.01.2010, 25.06.2014)
  ...
  i: 9997 | 9997  - getDayCount(01.01.2010, 16.05.2037)
  i: 9998 | 9998  - getDayCount(01.01.2010, 17.05.2037)
  i: 9999 | 9999  - getDayCount(01.01.2010, 18.05.2037)
lcnicolau
  • 3,252
  • 4
  • 36
  • 53
tomorrow
  • 1,260
  • 1
  • 14
  • 26
12

here's a small program which may help you:

import java.util.*;

public class DateDifference {
    public static void main(String args[]){
        DateDifference difference = new DateDifference();
    }

    DateDifference() {
        Calendar cal1 = new GregorianCalendar();
        Calendar cal2 = new GregorianCalendar();

        cal1.set(2010, 12, 1); 
        cal2.set(2011, 9, 31);
        System.out.println("Days= "+daysBetween(cal1.getTime(),cal2.getTime()));
    }

    public int daysBetween(Date d1, Date d2) {
        return (int)( (d2.getTime() - d1.getTime()) / (1000 * 60 * 60 * 24));
    }
}
Bondax
  • 3,143
  • 28
  • 35
talha2k
  • 24,937
  • 4
  • 62
  • 81
  • The one thing I would edit is: ``` public long daysBetween(Date d1, Date d2){ return ( (d2.getTime() - d1.getTime()) / (1000 * 60 * 60 * 24)); }``` – iamtodor Jan 17 '17 at 13:49
7
// http://en.wikipedia.org/wiki/Julian_day
public static int julianDay(int year, int month, int day) {
  int a = (14 - month) / 12;
  int y = year + 4800 - a;
  int m = month + 12 * a - 3;
  int jdn = day + (153 * m + 2)/5 + 365*y + y/4 - y/100 + y/400 - 32045;
  return jdn;
}

public static int diff(int y1, int m1, int d1, int y2, int m2, int d2) {
  return julianDay(y1, m1, d1) - julianDay(y2, m2, d2);
}
Wael Ellithy
  • 119
  • 1
  • 3
3

I'm really really REALLY new at Java, so i'm sure that there's an even better way to do what i'm proposing.

I had this same demand and i did it using the difference between the DAYOFYEAR of the two dates. It seemed an easier way to do it...

I can't really evaluate this solution in performance and stability terms, but i think it's ok.

here:

    public static void main(String[] args) throws ParseException {



//Made this part of the code just to create the variables i'll use.
//I'm in Brazil and the date format here is DD/MM/YYYY, but wont be an issue to you guys. 
//It will work anyway with your format.

    String s1 = "18/09/2014"; 
    String s2 = "01/01/2014";
    DateFormat f = DateFormat.getDateInstance();
    Date date1 = f.parse(s1); 
    Date date2 = f.parse(s2);




//Here's the part where we get the days between two dates.

    Calendar day1 = Calendar.getInstance();
    Calendar day2 = Calendar.getInstance(); 
    day1.setTime(date1);
    day2.setTime(date2);

    int daysBetween = day1.get(Calendar.DAY_OF_YEAR) - day2.get(Calendar.DAY_OF_YEAR);      




//Some code just to show the result...
    f = DateFormat.getDateInstance(DateFormat.MEDIUM);
    System.out.println("There's " + daysBetween + " days between " + f.format(day1.getTime()) + " and " + f.format(day2.getTime()) + ".");



    }

In this case, the output would be (remembering that i'm using the Date Format DD/MM/YYYY):

There's 260 days between 18/09/2014 and 01/01/2014.
Willi Mentzel
  • 27,862
  • 20
  • 113
  • 121
Breno RdV
  • 39
  • 3
  • 1
    This does not work because it only tells you the difference between the days of the year not the total running days. – Stosh15 Aug 18 '16 at 18:59
2

This function is good for me:

public static int getDaysCount(Date begin, Date end) {
    Calendar start = org.apache.commons.lang.time.DateUtils.toCalendar(begin);
    start.set(Calendar.MILLISECOND, 0);
    start.set(Calendar.SECOND, 0);
    start.set(Calendar.MINUTE, 0);
    start.set(Calendar.HOUR_OF_DAY, 0);

    Calendar finish = org.apache.commons.lang.time.DateUtils.toCalendar(end);
    finish.set(Calendar.MILLISECOND, 999);
    finish.set(Calendar.SECOND, 59);
    finish.set(Calendar.MINUTE, 59);
    finish.set(Calendar.HOUR_OF_DAY, 23);

    long delta = finish.getTimeInMillis() - start.getTimeInMillis();
    return (int) Math.ceil(delta / (1000.0 * 60 * 60 * 24));
}
Bondax
  • 3,143
  • 28
  • 35
0

My best solution (so far) for calculating the number of days difference:

//  This assumes that you already have two Date objects: startDate, endDate
//  Also, that you want to ignore any time portions

Calendar startCale=new GregorianCalendar();
Calendar endCal=new GregorianCalendar();

startCal.setTime(startDate);
endCal.setTime(endDate);

endCal.add(Calendar.YEAR,-startCal.get(Calendar.YEAR));
endCal.add(Calendar.MONTH,-startCal.get(Calendar.MONTH));
endCal.add(Calendar.DATE,-startCal.get(Calendar.DATE));

int daysDifference=endCal.get(Calendar.DAY_OF_YEAR);

Note, however, that this assumes less than a year's difference!

Community
  • 1
  • 1
DrDave
  • 718
  • 1
  • 7
  • 16
-10

If you're sick of messing with java you can just send it to db2 as part of your query:

select date1, date2, days(date1) - days(date2) from table

will return date1, date2 and the difference in days between the two.

Michael Sharek
  • 5,043
  • 2
  • 30
  • 33