# Thread: [Very Urgent] Need help calculating difference between two dates

1. Senior Member
Join Date
Jun 2008
Posts
2,565
Rep Power
8
And that is not the way to use a Calendar to get the difference. Doing it that way, you just as well use Date and a SimpleDateFormat with the timezone set.

Doing it that way, you will easily be a day off, or more, when counting years, months, etc, and not because of timezones.

Take measuring the difference from Feb 1 2008 to Feb 1 2009. Doing it the way you are you get 1 year and 1 day, since 1970 was not a leap year and 2008 was. You need to measure from the start date to the end date, using the actual dates, or you can expect problems.
Last edited by masijade; 02-18-2009 at 10:42 PM.

2. Senior Member
Join Date
Jun 2008
Posts
2,565
Rep Power
8
Here, go ahead and pick holes in it, but, aside from being "long-winded", and slower than other methods (although still only a few milliseconds, at most, even on the the test dates that are 1000 years apart, so it is still more than fast enough for 99.999999999% of all cases where it might be needed) it is guaranteed to be correct (as far as the GregorianCalendar itself, is correct).

Java Code:
```package datediffs;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import static java.util.Calendar.YEAR;
import static java.util.Calendar.DAY_OF_YEAR;
import static java.util.Calendar.MONTH;
import static java.util.Calendar.DAY_OF_MONTH;
import java.util.Date;
import java.util.GregorianCalendar;

public class Main {

private class DateDiff {
public int years;
public int months;
public int days;
public int hours;
public int mins;
public int secs;
public int millis;

@Override
public String toString() {
StringBuilder sb = new StringBuilder();
if (years > 0) sb.append("Years:  ").append(years).append("  ");
if (months > 0) sb.append("Months:  ").append(months).append("  ");
if (days > 0) sb.append("Days:  ").append(days).append("  ");
if (hours > 0) sb.append("Hours:  ").append(hours).append("  ");
if (mins > 0) sb.append("Minutes:  ").append(mins).append("  ");
if (secs > 0) sb.append("Seconds:  ").append(secs).append("  ");
if (millis > 0) sb.append("Milliseconds:  ").append(millis).append("  ");
if (sb.length() > 0) sb.delete(sb.length() -2, sb.length());
return sb.toString();
}
}

private DateDiff getDifference(Date startDate, Date endDate) {
if (startDate.after(endDate)) return null;

DateDiff diff = new DateDiff();
Calendar start = new GregorianCalendar();
Calendar end = new GregorianCalendar();

start.setTime(startDate);
end.setTime(endDate);

diff.years = end.get(YEAR) - start.get(YEAR);
if (start.after(end)) {
diff.years--;
}

do {
diff.months++;
} while (start.before(end));
diff.months--;

do {
diff.days++;
} while (start.before(end));
diff.days--;

long rest = end.getTimeInMillis() - start.getTimeInMillis();
diff.hours = (int) rest/3600000;
rest %= 3600000;
diff.mins = (int) rest/60000;
rest %= 60000;
diff.secs = (int) rest/1000;
diff.millis = (int) rest % 1000;

return diff;
}

private DateDiff getDifferenceInDays(Date startDate, Date endDate) {
if (startDate.after(endDate)) return null;

DateDiff diff = new DateDiff();
Calendar start = new GregorianCalendar();
Calendar end = new GregorianCalendar();

start.setTime(startDate);
end.setTime(endDate);

if (start.get(YEAR) < end.get(YEAR)) {
// Adjust for the first of the next year
diff.days = start.getActualMaximum(DAY_OF_YEAR) - start.get(DAY_OF_YEAR) + 1;
}

while (start.get(YEAR) < end.get(YEAR)) {
diff.days += start.getActualMaximum(DAY_OF_YEAR);
}
if (start.after(end)) {
// only need to remove one day
diff.days -= 1;
}

while (start.get(MONTH) < end.get(MONTH)) {
diff.days += start.getActualMaximum(DAY_OF_MONTH);
}
if (start.after(end)) {
diff.days -= start.getActualMaximum(DAY_OF_MONTH);
}

do {
diff.days++;
} while (start.before(end));
diff.days--;

long rest = end.getTimeInMillis() - start.getTimeInMillis();
diff.hours = (int) rest/3600000;
rest %= 3600000;
diff.mins = (int) rest/60000;
rest %= 60000;
diff.secs = (int) rest/1000;
diff.millis = (int) rest % 1000;

return diff;
}

public static void main(String[] args) throws ParseException {
Main main = new Main();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss.SSS");
Date start = sdf.parse("2008/2/1 12:00:00.000");
Date end = sdf.parse("2009/2/1 13:00:00.000");
System.out.println(main.getDifference(start, end));
System.out.println(main.getDifferenceInDays(start, end));
System.out.println();
System.out.println();
System.out.println();
start = sdf.parse("2008/2/1 12:00:00.000");
end = sdf.parse("2009/2/1 11:00:00.000");
System.out.println(main.getDifference(start, end));
System.out.println(main.getDifferenceInDays(start, end));
System.out.println();
System.out.println();
System.out.println();
start = sdf.parse("1008/2/1 12:00:00.000");
end = sdf.parse("2009/2/1 11:00:00.000");
System.out.println(main.getDifference(start, end));
System.out.println(main.getDifferenceInDays(start, end));
}
}```
Last edited by masijade; 02-19-2009 at 10:26 AM.

3. Doing it that way, you will easily be a day off, or more, when counting years, months, etc, and not because of timezones.
Last edited by Steve11235; 02-19-2009 at 04:43 AM. Reason: ..........

4. ## Corrected code

Sorry for my earlier mistake. Here is an approach using calendars that handles exceptional conditions.

Note that leap days between dates are only accounted for when the start or end date is in February of a leap year. That is the correct solution, since years, months, days type descriptions are inherently imprecise.
Java Code:
```package test;

import static java.util.Calendar.YEAR;
import static java.util.Calendar.MONTH;
import static java.util.Calendar.DATE;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.TimeZone;

/**
* DateDifferenceTest
*/
public class DateDifferenceTest {
/**
* Determine the difference between two Date's in years, months, and days
* <p>
* <b>Note:</b>
*
* @param pDate1
* @param pDate2
* @return a String containing the information
*/
public static String dateDifference(final Date pDate1,
final Date pDate2) {
final String diffString;
final int startMonth, startDay;
int years = 0, months = 0, days = 0;
boolean isNegative = false;
GregorianCalendar gc1 = null, gc2 = null;
gc1 = new GregorianCalendar();
gc1.setTimeZone(TimeZone.getTimeZone("GMT"));
gc2 = new GregorianCalendar();
gc2.setTimeZone(TimeZone.getTimeZone("GMT"));
/*
* Handle pDate2 after pDate1
*/
if (!pDate1.before(pDate2)) {
gc1.setTimeInMillis(pDate1.getTime());
gc2.setTimeInMillis(pDate2.getTime());
}
else {
isNegative = true;
gc1.setTimeInMillis(pDate2.getTime());
gc2.setTimeInMillis(pDate1.getTime());
}
/*
* Special case: same year and month
*/
if (gc1.get(YEAR) == gc2.get(YEAR)
&& gc1.get(MONTH) == gc2.get(MONTH)) {
days = gc1.get(DATE)
- gc2.get(DATE);
}
/*
* Normal case
*/
else {
/*
* Capture the start day. This is necessary because incrementing the month moves the day back
* to the last day of that month.
*/
startDay = gc2.get(DATE);
/*
* If the day of the end month is less than the day of the start month, increment the start
* date until the beginning of the next month, count the days
*/
if (gc1.get(DATE) < gc2.get(DATE)) {
startMonth = gc2.get(MONTH);
while (startMonth == gc2.get(MONTH)) {
days++;
1);
}
}
/*
* Handle years
*/
do {
years++;
1);
}
while (!gc1.before(gc2));
years--;
-1);
/*
* Handle months
*/
do {
months++;
1);
}
while (!gc1.before(gc2));
months--;
-1);
/*
* Handle days
*/
if (gc1.get(DATE) < startDay) {
days += gc1.get(DATE) - 1;
}
else {
days = gc1.get(DATE)
- startDay;
}
}
/*
* Format response
*/
diffString = (isNegative
? "2nd before 1st; "
: "")
+ "Years: "
+ years
+ "; Months: "
+ months
+ "; Days: "
+ days;
return diffString;
}

/**
* Entry point for test
*
* @param args
*/
public static void main(final String[] args) {
final Date date1, date2;
/*
* IMPORTANT: Months are zero based: 0 = Jan, 1 = Feb, etc.
*/
date1 = (new GregorianCalendar(2008,
1,
1)).getTime();
date2 = (new GregorianCalendar(2008,
1,
1)).getTime();
System.out.println(dateDifference(date1,
date2));
}
}```

Page 2 of 2 First 12

#### Posting Permissions

• You may not post new threads
• You may not post replies
• You may not post attachments
• You may not edit your posts
•