1

So for an assignment we HAVE to use the JDK Date or Calendar objects to represent dates in the system we are designing (otherwise I'd be using another library). For a function I need to make sure that at least a certain number of years has passed since the input date to the present date. I wrote the following method to try and calculate the days between two Calendar objects:

public static int daysSince(Calendar pastDate) {
    Calendar presentDate = Calendar.getInstance();

    int daysSince = 0;

    while (pastDate.before(presentDate)) {
        pastDate.add(Calendar.DAY_OF_MONTH, 1);
        daysSince++;
    } return daysSince;
}

However, this method always seems to return exactly 30 days less than the actual number of days between the two dates, and I can't seem to figure out why? For example, it says there is only one day between 3/25/2016 and 4/25/2016. What am I missing?

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
transiti0nary
  • 493
  • 6
  • 25

3 Answers3

2

Your code works (proof), mostly. I suspect that what's wrong is your test data.

For example, it says there is only one day between 3/25/2016 and 4/25/2016.

I suspect you created that test date (3/25/2016) incorrectly. Remember that MONTH values start with 0, so to create 3/25/2016 you'd need:

past.set(Calendar.DAY_OF_MONTH, 25);
past.set(Calendar.MONTH, 2);           // NOTE THE 2
past.set(Calendar.YEAR, 2016);

I suspect you used 3 where you needed 2, and the one day you were seeing was because your test date was at midnight and your current date wasn't.

Other than that you probably want to handle times better, that code works.

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
  • 1
    @transiti0nary: Fundamentally changing questions once they're answered (or frankly even before, as people are likely working on answers) is not appropriate on SO; questions are not meant to be moving targets. If you have a new question, ask a new question. I've rolled back the edit (you can still grab its content [here](http://stackoverflow.com/posts/36837338/revisions) for building your new question). – T.J. Crowder Apr 25 '16 at 10:47
0

Instead of looping, you could do it like this:

public static int daysSince(Calendar pastDate) {
    Calendar presentDate = Calendar.getInstance();
    long millisInADay = 1000 * 60 * 60 * 24;

    return(pastDate.getTimeInMillis()-presentDate.getTimeInMillis())/millisInADay;
}
Çelebi Murat
  • 168
  • 11
  • See [here](http://stackoverflow.com/a/3491711/157247) for why doing this naively is a bad idea. – T.J. Crowder Apr 25 '16 at 10:47
  • Thanks. I did produce another implementation that didn't involve looping, however now I am having the problem of converting days into years whilst taking leap year into consideration. Is there any sort of conversion tool in the JDK similar to the TimeUnit enum that I used in my implementation that could achieve this? Thank you – transiti0nary Apr 25 '16 at 10:48
  • I think using LocalDate would be the best approach in this case. https://docs.oracle.com/javase/8/docs/api/java/time/LocalDate.html – Çelebi Murat Apr 25 '16 at 10:54
  • @T.J.Crowder, thanks for the input. The code I wrote is just for presenting the general idea. It is very easy to modify it according to the specifications required. – Çelebi Murat Apr 25 '16 at 11:01
-1

Make sure while setting the past date, that months are considered form 0-11.

Calendar presentDate = Calendar.getInstance(); //25th April, 2016
    Calendar pastDate = Calendar.getInstance();
    pastDate.set(2016, 2, 25); //its 25th March, 2016 here
    int daysSince = 0;
    while(pastDate.before(presentDate)){
        pastDate.add(Calendar.DAY_OF_MONTH, 1);
        daysSince++;
    }
    System.out.println(daysSince);
//output : 31
Mohit
  • 126
  • 1
  • 9
  • Thanks, I was simply forgetting 0-indexing. However I now ran into another issue, I updated the original post describing it. – transiti0nary Apr 25 '16 at 10:46