I want to calculte the no of Days( difference between the 2 given dates) using simple java. I have written a code to calculate those difference. But it was not fit for the Leap year. So please help me out from this .
Note: It should work for the Leap Year too.

You don't show your code, so it's pretty hard to explain why leap years would be a problem. But if you had used a class which knew about leap years -- like the Calendar class -- you would not have had that problem. So I would suggest rewriting your code to use Calendar objects.

Don't say anything - you calculated the difference in milliseconds, then converted that to days by using the ever constant "1 day == 24 hours == 1440 minutes == 86400 seconds == 86400000 milliseconds" transformation. No wonder that's broken; what about daylight savings time?

As said, java.util.Calendar can help you out. Turn both dates into Calendar objects (Calendar's setTime method should help you there). Then add one day to the chronologically first one until it has the same day as the other one. The number of additions is the difference in days.

Or use Joda-Time; its Days class has a static method that takes two ReadablePartial (which is implemented by LocalDate) instances and returns a Days instance. Its getDays() method then returns the number of days.

That's almost what I had in mind. That will not work properly if initially the time of day of start is also less than the time of day of current. For instance, if start is yesterday at 12:00 and current is today at 13:00, then that code would show a date difference of 2 days - adding 1 results in today at 12:00 which is still less than today at 13:00, so another 1 is added. You can solve this by explicitly setting the time of day of both calendars to the same time; don't forget the milliseconds though.

Rajani Gummadi
Ranch Hand

Joined: Dec 17, 2010
Posts: 48

posted

0

Hi Rob,

There is one question troubling me a bit on the approach you suggested, though my test against that logic proved satisfactory. We are adding a day from the starting day and comparing that with the current, this is pretty straightforward and looking great to me. Thanks for that. But I'm just thinking, if my program has to run for say 100 years from now, and it needs to calculate every day, that is time complexity is increasing as we move on. I did a sample test with the start day as Mar 01, 2011 and changed my system date to 01/01/2099 and ran the code... well I did not notice any significant increase in completing the loop. but would that have any impact in production, where other facts and load is considered.

Also, how much can we loose, if we follow calculating millis and dividing by 24 * 60 * 60 *1000.

First we have a suspicion of a performance problem in a hypothetical environment. Next we have a rhetorical question designed to scare people into acting on this purely hypothetical performance problem. And finally, we have a test to see if this hypothetical performance problem is actually real, and apparently it isn't. (At least we had the test -- that was a good thing.) But even though it doesn't seem to be a problem, we still have a proposed "solution" to it which has already been shown to be deficient. (As Rob Spoor said a long time ago, what about daylight saving time?)

shivarama krishna
Greenhorn

Joined: Jan 10, 2008
Posts: 4

posted

0

Hi,
Thanks for your reply, but the main issue with what you told is Leap Year.
Please have a look into my code

Calendar calendar1 = Calendar.getInstance();
Calendar calendar2 = Calendar.getInstance();
calendar1.set(2007, 01, 10);
calendar2.set(2007, 07, 01);
long milliseconds1 = calendar1.getTimeInMillis();
long milliseconds2 = calendar2.getTimeInMillis();
long diff = milliseconds2 - milliseconds1;

long diffDays = diff / (24 * 60 * 60 * 1000);
System.out.println("\nThe Date Different Example");

System.out.println("Time in days: " + diffDays + " days.");

but it will give wrong result for Leap year. So,what would be the correct solutions for this.
Thanks in advance.

Actually you're very close. Try doing the division using floating-point arithmetic, and round the result:

The 24.0 will force the entire calculation to be done using floating-point. And Math.round() will get you the integer closest to to result. Since daylight savings will cause your result to be off by at most one hour, the number of days may be off by 1/24 either way. Using Math.round() solves this easily.

Mike Simmons
Ranch Hand

Joined: Mar 05, 2008
Posts: 3020

10

posted

0

Note also that if you get the time representations from some other source, such as a Date, you may need to remove unwanted effects of hours, minutes and seconds by explicitly setting those parts of the calendar to some standard time, as Rob noted above:

This isn't an issue for the code you showed - but it might be an issue for the "real" code, depending how you get those calendar objects.

There is one question troubling me a bit on the approach you suggested, though my test against that logic proved satisfactory. We are adding a day from the starting day and comparing that with the current, this is pretty straightforward and looking great to me. Thanks for that. But I'm just thinking, if my program has to run for say 100 years from now, and it needs to calculate every day, that is time complexity is increasing as we move on. I did a sample test with the start day as Mar 01, 2011 and changed my system date to 01/01/2099 and ran the code... well I did not notice any significant increase in completing the loop. but would that have any impact in production, where other facts and load is considered.

There is another way to solve this, one I've used in a date difference method of my own. Take the day of the year of both calendar objects. Then, while the year is different, add the number of days in the year of first calendar object (first.getActualMaximum(Calendar.DAY_OF_YEAR)) and increase that calendar object with a full year. The following example will show how that works:
- first = 2011-03-01, second = 2013-01-01
- day of year of first is 31 + 28 + 1 == 60, day of year of second is 1; the intermediate difference is now -59
- first has year 2011 so there are 365 days in the year. Add that to the difference (306) and increase the year to 2012
- first has year 2012 so there are 366 days in the year. Add that to the difference (672) and increase the year to 2013
- the years are now equal so the total difference is 672 days.

Also, how much can we loose, if we follow calculating millis and dividing by 24 * 60 * 60 *1000.

At most one day, if the rounding is not right and you use midnight as measuring point. If the first day is the day where you get one hour extra, adding 24 will not be midnight the next day but 11 PM on the same day.

Mike Simmons
Ranch Hand

Joined: Mar 05, 2008
Posts: 3020

10

posted

0

Rob Spoor wrote:There is another way to solve this

Yeah, it's unfortunate that Calendar does not have a get(Calendar.JULIAN_DAY_NUMBER) option (in the astronomical sense). Or something similar. One could precompute an array for the JDN at the beginning if each year (within some range), and then use this plus the DAY_OF_YEAR (and minus 1) to quickly find the JDN for any date of interest.

----

Rob Spoor wrote:

Also, how much can we loose, if we follow calculating millis and dividing by 24 * 60 * 60 *1000.

At most one day, if the rounding is not right and you use midnight as measuring point. If the first day is the day where you get one hour extra, adding 24 will not be midnight the next day but 11 PM on the same day.

I don't think it matters whether you use midnight or some other time as the measuring point, as long as all dates involved use the same measuring point. You get the same problem with using noon for example - noon the day before daylight saving is 23 hours before noon the first day of daylight saving. And in fall the analogous times are 25 hours apart. Same problem as if we'd used midnight, or any other standard time.

If for some reason someone doesn't trust the result of Math.round(), one could also treat the answer it gives as an approximation, and use that value to skip the Calendar ahead by that amount - then adjust it backward or forward one day at a time, like the original loop solution above. Except it will never actually be necessary to make that correction, since round() does give the right answer. But whatever.