Days between 2 dates [Java]

Soldato
Joined
24 Apr 2011
Posts
5,455
Guys, I need your help. I am trying to work out how to calculate the number of NIGHTS between 2 dates. Therefore, the number of nights between 1st Jan and 31st Jan is 30, and the number between 1st Jan and 1st Feb is 31.

Here is what I have till now:
import java.util.*;
public class DateDifference {
int day1, day2, month1, month2, year1, year2, days;
public static void main(String args[]){
DateDifference difference = new DateDifference();
}
DateDifference() {
Calendar cal1 = new GregorianCalendar();
Calendar cal2 = new GregorianCalendar();

Scanner sc = new Scanner (System.in);

System.out.println("Enter Day:");
day1 = sc.nextInt();
System.out.println("Enter Month:");
month1 = sc.nextInt();
System.out.println("Enter Year:");
year1 = sc.nextInt();
System.out.println("Enter Day:");
day2 = sc.nextInt();
System.out.println("Enter Month:");
month2 = sc.nextInt();
System.out.println("Enter Year:");
year2 = sc.nextInt();

cal1.set(year1, month1, day1);
cal2.set(year2, month2,day2);
System.out.println("Days= "+daysBetween(cal1.getTime(),cal2.getTime()));
}
public int daysBetween(Date cal1, Date cal2){
return (int)( (cal2.getTime() - cal1.getTime()) / (1000 * 60 * 60 * 24));
}
}

Shamelessly, i took a template off the internet and modded it to my use. Anyway, it works fine when I use dates in the same month, but goes haywire when i chose different months.

To use the same examples as before, it gives me 30 days between 1st Jan and 31st Jan, but 29 days between 1st Jan and 1st Feb.

Any ideas?

Its probably blatantly obvious, but I can't see it.
 
I might be missing the blatantly obvious but I don't think theres any simple one line formula for doing it - you probably have to work out the remaining days in the start month then use a while loop to iterate through the months/years until you hit the end month/year based on an array for each month and how many days it has. Then add how many days you are into the end month.

Or theres already a function for it in Java but I'm not overly familiar with the language.


EDIT: Google has a load of hits for doing exactly what you want including this which probably has an answer http://stackoverflow.com/questions/3299972/difference-in-days-between-two-dates-in-java
 
Last edited:
I might be missing the blatantly obvious but I don't think theres any simple one line formula for doing it - you probably have to work out the remaining days in the start month then use a while loop to iterate through the months/years until you hit the end month/year based on an array for each month and how many days it has. Then add how many days you are into the end month.

Or theres already a function for it in Java but I'm not overly familiar with the language.


EDIT: Google has a load of hits for doing exactly what you want including this which probably has an answer http://stackoverflow.com/questions/3299972/difference-in-days-between-two-dates-in-java
I was thinking that, but my teacher at school told me that there is the Calendar method which makes things MUCH easier.

I looked at the link you posted already, but it sounded very different to what was told to me, and what i was doing, but maybe it could be the answer. I'll look at it again.

Thanks.
Where I work, we recommend you use Jodatime to do date calculations

have a look at: http://joda-time.sourceforge.net/

and: http://stackoverflow.com/questions/3802893/number-of-days-between-two-dates-in-jodatime

Thanks a lot.
 
I only scanned your code but I would take a date in the format: dd/mm/YYYY and then strip the slashes so you only have two inputs rather than six.

You also know the Java calendar starts from 0 rather than 1?
 
I only scanned your code but I would take a date in the format: dd/mm/YYYY and then strip the slashes so you only have two inputs rather than six.

You also know the Java calendar starts from 0 rather than 1?

I was just doing a rough draft.

Yes, but I can't really see what that would change :p
 
It would seem that this is one area that Java sucks. In C# it would be simple:

Code:
var date1 = new DateTime(2013, 01, 01);
var date2 = new DateTime(2013, 01, 31);

var timespan = date2 - date1;

Console.WriteLine("Nights between {0} and {1} is: {2}", date1, date2, timespan.Days - 1);
 
It would seem that this is one area that Java sucks. In C# it would be simple:

Code:
var date1 = new DateTime(2013, 01, 01);
var date2 = new DateTime(2013, 01, 31);

var timespan = date2 - date1;

Console.WriteLine("Nights between {0} and {1} is: {2}", date1, date2, timespan.Days - 1);

I am doing a program for my A-Level, I can't just change language :P

Didn't try Joda Time yet.
 
Ha, sorry, I didn't mean that to sound so harsh!

I think the easiest way to do this would be to convert the dates to unix time stamps, subtract the former from the latter, then divvy up the remainder into days.
 
I am doing a program for my A-Level, I can't just change language :P

Didn't try Joda Time yet.

In Java when working with dates/time use Joda Time as suggested by agent_paul as the built in stuff sucks. The examples provided on the website should have everything you need. Good luck. :)
 
Yes, but I can't really see what that would change :p

If you enter 3 for month. That's actually April not March. So you need to account for that in your code.

Joda time is a lot simpler and takes the input as you would expect. The API is pretty nifty too.
 
Last edited:
Ha, sorry, I didn't mean that to sound so harsh!

I think the easiest way to do this would be to convert the dates to unix time stamps, subtract the former from the latter, then divvy up the remainder into days.
Pfft, don't worry! It didn't sound harsh to me :P
In Java when working with dates/time use Joda Time as suggested by agent_paul as the built in stuff sucks. The examples provided on the website should have everything you need. Good luck. :)
Yeah, I looked on the site and it looks helpful. Thanks.
If you enter 3 for month. That's actually April not March. So you need to account for that in your code.

Joda time is a lot simpler and takes the input as you would expect. The API is pretty nifty too.

Yeah, but if I take it standard with everything it shouldn't change much. I'll look at that after I do everything.
 
I think you're being bitten by the API as uniQ pointed out. Creating a GregorianCalendar is ZERO-based for the month (i.e. 0=january). See http://docs.oracle.com/javase/1.5.0...alendar.html#GregorianCalendar(int, int, int) This seems to work:

Code:
import java.util.Calendar;
import java.util.GregorianCalendar;

public class DatePlay
{
    private static final long MILLIS_IN_A_DAY = 1000 * 60 * 60 * 24;

    public static final int daysBetween(final Calendar start, final Calendar end)
    {
        return (int)((end.getTimeInMillis() - start.getTimeInMillis()) / MILLIS_IN_A_DAY) ;
    }
    
    public static void main(String[] args)
    {
        final Calendar firstJan = new GregorianCalendar(2013, 0, 1);
        final Calendar lastJan = new GregorianCalendar(2013, 0, 31);
        final Calendar firstFeb = new GregorianCalendar(2013, 1, 1);
        System.out.println(daysBetween(firstJan, lastJan));
        System.out.println(daysBetween(firstJan, firstFeb));
    }
}
 
Yeah, but if I take it standard with everything it shouldn't change much. I'll look at that after I do everything.

Final clue not all months have the same amount of days. If you can't see why you need to account for this I'll let you carry on your merry way :)
 
So now we've got that out the way simply -1 for your month inputs to get the correct days:

Code:
        cal1.set(year1, month1-1, day1);
        cal2.set(year2, month2-1, day2);

There's no need to use the Gregorian Calendar either so change that to:
Code:
        Calendar cal1 = Calendar.getInstance();
        Calendar cal2 = Calendar.getInstance();
 
So now we've got that out the way simply -1 for your month inputs to get the correct days:

Code:
        cal1.set(year1, month1-1, day1);
        cal2.set(year2, month2-1, day2);

There's no need to use the Gregorian Calendar either so change that to:
Code:
        Calendar cal1 = Calendar.getInstance();
        Calendar cal2 = Calendar.getInstance();

Yup, done that quick fix already.

And cheers for the tip.

I will continue tonight and post if I need any more help.
 
IGNORE, I WORKED IT OUT.

Up till now, everything has been running smoothly. I have altered the program to work as suggested; enter the date as dd/mm/yyyy, then extract the date/month/year out of that. I am now doing a validation for the date format, meaning if they enter d/mm/yyyy or dd/m/yyyy it gives them an error and they have to re-input the date.

I am using a do/while loop, comparing the sub string (where I should have a /) to a defined String (containing /). If they all match (they are all /) then the boolean variable is true, and the program continues. If it finds something other than / it will display an error message and loop back to the start of when it asks for the date. It is taking it ALWAYS as false (even when my input is correct) and even then, it is not re-looping back.

Code:
import java.util.*;
 public class DateDifference {
     int day1, day2, month1, month2, year1, year2;
     String startdate, enddate, day1S, day2S, month1S, month2S, year1S, year2S;
     String datevalidation = "/";
     boolean dval;
    public static void main(String args[]){
        DateDifference difference = new DateDifference();
    }
    DateDifference() {
        Calendar cal1 = Calendar.getInstance();
        Calendar cal2 = Calendar.getInstance();
        
        Scanner sc = new Scanner (System.in);
        do {
        System.out.println("Enter Start Date [dd/mm/yyyy]:");
        startdate = sc.next();
        System.out.println("Enter End Date [dd/mm/yyyy]:");
        enddate = sc.next();
        
        int l1 = startdate.length();
        int l2 = enddate.length();
        day1S = startdate.substring(0,2);
        month1S = startdate.substring(3,5);
        year1S = startdate.substring(6,l1);
        
        day2S = enddate.substring(0,2);
        month2S = enddate.substring(3,5);
        year2S = enddate.substring(6,l2);
        
        if (startdate.substring(2,3).equals(datevalidation) & startdate.substring(5,6).equals(datevalidation) & enddate.substring(2,3).equals(datevalidation) & enddate.substring(5,6).equals(datevalidation)) 
            dval = true;
        
        else 
            dval = false;
            System.out.println("Wrong date format. Try again");
        
       } while (dval = false);
       
       day1 = Integer.parseInt(day1S);
       month1 = Integer.parseInt(month1S);
       year1 = Integer.parseInt(year1S);
       day2 = Integer.parseInt(day2S);
       month2 = Integer.parseInt(month2S);
       year2 = Integer.parseInt(year2S);
       
        cal1.set(year1, month1 - 1, day1); 
        cal2.set(year2, month2 - 1,day2);
        System.out.println("Days= "+daysBetween(cal1.getTime(),cal2.getTime()));
    }
    public int daysBetween(Date cal1, Date cal2){
        return (int)( (cal2.getTime() - cal1.getTime()) / (1000 * 60 * 60 * 24));
    }
 }

Really should have paid more attention in class eh!!

I'm probably going to look so stupid, but hey, at least i am seeking help, no?

Screenshots

When my input is correct:
2100RYdaSM1T6EXLqgq5.png

When input is not correct:
9qSEwDKSTIdLAWmxS_Cy.png

It tells me that it can't convert 1/ to an integer, which is fine. As you can see, it is not looping.
 
Last edited:
Back
Top Bottom