Difference in days between two dates in Java?

2018-12-31 10:07发布

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.

20条回答
ら面具成の殇う
2楼-- · 2018-12-31 10:11

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.

ZonedDateTime now = ZonedDateTime.now();
ZonedDateTime oldDate = now.minusDays(1).minusMinutes(10);
Duration duration = Duration.between(oldDate, now);
System.out.println(duration.toDays());

ChronoUnit

If all you need is the number of days, alternatively you can use the ChronoUnit enum. Notice the calculation methods return a long rather than int.

long days = ChronoUnit.DAYS.between( then, now );
查看更多
骚的不知所云
3楼-- · 2018-12-31 10:12

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.

查看更多
荒废的爱情
4楼-- · 2018-12-31 10:12

If you're looking for a solution that returns proper number or days between e.g. 11/30/2014 23:59 and 12/01/2014 00:01 here's solution using Joda Time.

private int getDayDifference(long past, long current) {
    DateTime currentDate = new DateTime(current);
    DateTime pastDate = new DateTime(past);
    return currentDate.getDayOfYear() - pastDate.getDayOfYear();
} 

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 that 0 would be returned because there's only 2 minutes difference between these two dates.

查看更多
美炸的是我
5楼-- · 2018-12-31 10:16
public static int getDifferenceIndays(long timestamp1, long timestamp2) {
    final int SECONDS = 60;
    final int MINUTES = 60;
    final int HOURS = 24;
    final int MILLIES = 1000;
    long temp;
    if (timestamp1 < timestamp2) {
        temp = timestamp1;
        timestamp1 = timestamp2;
        timestamp2 = temp;
    }
    Calendar startDate = Calendar.getInstance(TimeZone.getDefault());
    Calendar endDate = Calendar.getInstance(TimeZone.getDefault());
    endDate.setTimeInMillis(timestamp1);
    startDate.setTimeInMillis(timestamp2);
    if ((timestamp1 - timestamp2) < 1 * HOURS * MINUTES * SECONDS * MILLIES) {
        int day1 = endDate.get(Calendar.DAY_OF_MONTH);
        int day2 = startDate.get(Calendar.DAY_OF_MONTH);
        if (day1 == day2) {
            return 0;
        } else {
            return 1;
        }
    }
    int diffDays = 0;
    startDate.add(Calendar.DAY_OF_MONTH, diffDays);
    while (startDate.before(endDate)) {
        startDate.add(Calendar.DAY_OF_MONTH, 1);
        diffDays++;
    }
    return diffDays;
}
查看更多
后来的你喜欢了谁
6楼-- · 2018-12-31 10:17

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. The Days class provides a type-safe way of representing a number of days in your application. The class includes convenient constants for ZERO and ONE.

Given the old outmoded java.util.Date objects in the Question, first convert them to modern java.time.Instant objects. The old date-time classes have newly added methods to facilitate conversion to java.time, such a java.util.Date::toInstant.

Instant start = utilDateStart.toInstant(); // Inclusive.
Instant stop = utilDateStop.toInstant();  // Exclusive.

Pass both Instant objects to factory method for org.threeten.extra.Days.

In the current implementation (2016-06) this is a wrapper calling java.time.temporal.ChronoUnit.DAYS.between, read the ChronoUnit class doc for details. To be clear: all uppercase DAYS is in the enum ChronoUnit while initial-cap Days is a class from ThreeTen-Extra.

Days days = Days.between( start , stop );

You can pass these Days objects around your own code. You can serialize to a String in the standard ISO 8601 format by calling toString. This format of PnD uses a P to mark the beginning and D 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.

String output = days.toString();

P3D

Days days = Days.parse( "P3D" );  
查看更多
时光乱了年华
7楼-- · 2018-12-31 10:19

It depends on what you define as the difference. To compare two dates at midnight you can do.

long day1 = ...; // in milliseconds.
long day2 = ...; // in milliseconds.
long days = (day2 - day1) / 86400000;
查看更多
登录 后发表回答