I need to find the number of days between two dates: one is from a report and one is the current date. My snippet:
int age=calculateDifference(agingDate, today);
Here calculateDifference
is a private method, agingDate
and today
are Date
objects, just for your clarification. I've followed two articles from a Java forum, Thread 1 / Thread 2.
It works fine in a standalone program although when I include this into my logic to read from the report I get an unusual difference in values.
Why is it happening and how can I fix it?
EDIT :
I'm getting a greater number of days compared to the actual amount of Days.
public static int calculateDifference(Date a, Date b)
{
int tempDifference = 0;
int difference = 0;
Calendar earlier = Calendar.getInstance();
Calendar later = Calendar.getInstance();
if (a.compareTo(b) < 0)
{
earlier.setTime(a);
later.setTime(b);
}
else
{
earlier.setTime(b);
later.setTime(a);
}
while (earlier.get(Calendar.YEAR) != later.get(Calendar.YEAR))
{
tempDifference = 365 * (later.get(Calendar.YEAR) - earlier.get(Calendar.YEAR));
difference += tempDifference;
earlier.add(Calendar.DAY_OF_YEAR, tempDifference);
}
if (earlier.get(Calendar.DAY_OF_YEAR) != later.get(Calendar.DAY_OF_YEAR))
{
tempDifference = later.get(Calendar.DAY_OF_YEAR) - earlier.get(Calendar.DAY_OF_YEAR);
difference += tempDifference;
earlier.add(Calendar.DAY_OF_YEAR, tempDifference);
}
return difference;
}
Note :
Unfortunately, none of the answers helped me solve the problem. I've accomplished this problem with the help of Joda-time library.
java.time
In Java 8 and later, use the java.time framework (Tutorial).
Duration
The
Duration
class represents a span of time as a number of seconds plus a fractional second. It can count days, hours, minutes, and seconds.ChronoUnit
If all you need is the number of days, alternatively you can use the
ChronoUnit
enum. Notice the calculation methods return along
rather thanint
.You say it "works fine in a standalone program," but that you get "unusual difference values" when you "include this into my logic to read from report". That suggests that your report has some values for which it doesn't work correctly, and your standalone program doesn't have those values. Instead of a standalone program, I suggest a test case. Write a test case much as you would a standalone program, subclassing from JUnit's TestCase class. Now you can run a very specific example, knowing what value you expect (and don't give it today for the test value, because today changes over time). If you put in the values you used in the standalone program, your tests will probably pass. That's great - you want those cases to keep working. Now, add a value from your report, one that doesn't work right. Your new test will probably fail. Figure out why it's failing, fix it, and get to green (all tests passing). Run your report. See what's still broken; write a test; make it pass. Pretty soon you'll find your report is working.
If you're looking for a solution that returns proper number or days between e.g.
11/30/2014 23:59
and12/01/2014 00:01
here's solution using Joda Time.This implementation will return
1
as a difference in days. Most of the solutions posted here calculate difference in milliseconds between two dates. It means that0
would be returned because there's only 2 minutes difference between these two dates.ThreeTen-Extra
The Answer by Vitalii Fedorenko is correct, describing how to perform this calculation in a modern way with java.time classes (
Duration
&ChronoUnit
) built into Java 8 and later (and back-ported to Java 6 & 7 and to Android).Days
If you are using a number of days routinely in your code, you can replace mere integers with use of a class. The
Days
class can be found in the ThreeTen-Extra project, an extension of java.time and proving ground for possible future additions to java.time. TheDays
class provides a type-safe way of representing a number of days in your application. The class includes convenient constants forZERO
andONE
.Given the old outmoded
java.util.Date
objects in the Question, first convert them to modernjava.time.Instant
objects. The old date-time classes have newly added methods to facilitate conversion to java.time, such ajava.util.Date::toInstant
.Pass both
Instant
objects to factory method fororg.threeten.extra.Days
.In the current implementation (2016-06) this is a wrapper calling
java.time.temporal.ChronoUnit.DAYS.between
, read theChronoUnit
class doc for details. To be clear: all uppercaseDAYS
is in the enumChronoUnit
while initial-capDays
is a class from ThreeTen-Extra.You can pass these
Days
objects around your own code. You can serialize to a String in the standard ISO 8601 format by callingtoString
. This format ofPnD
uses aP
to mark the beginning andD
means “days”, with a number of days in between. Both java.time classes and ThreeTen-Extra use these standard formats by default when generating and parsing Strings representing date-time values.It depends on what you define as the difference. To compare two dates at midnight you can do.