-1

I need a method which returns the difference in days between the current day and other any date, I have the following:

private long getDays(Date dateOp) {
    Calendar feCurrent=Calendar.getInstance();
    feCurrent.set(Calendar.HOUR_OF_DAY, 0);
    feCurrent.set(Calendar.MINUTE, 0);
    feCurrent.set(Calendar.SECOND, 0);

    Calendar feAna=Calendar.getInstance();
    feAna.setTime(dateOp);
    feAna.set(Calendar.HOUR_OF_DAY, 0);
    feAna.set(Calendar.MINUTE, 0);
    feAna.set(Calendar.SECOND, 0);
    feAna.getTime());
    long timeDiff = Math.abs(feAna.getTime().getTime() - feCurrent.getTime().getTime());

    return TimeUnit.MILLISECONDS.toDays(timeDiff);
}

The thing is I'm always getting one day less, for example, if the date as parameter is Octuber 16th 2017, the result will 3, but it's actually four, I debugged and the timeDiff for those dates is 345599395 , when converted to days is 3.999....

Does anyone have idea why it's not working.

By the way the date as parameter is load from a database, because if I tried with a main setting both dates it works.

zepol
  • 187
  • 5
  • 20
  • `feAna.set(Calendar.MILLISECOND, 0)` –  Oct 12 '17 at 19:31
  • Try to also set the milliseconds to `0` for both calendar instances. `cal.set(Calendar.MILLISECOND, 0)` – Titus Oct 12 '17 at 19:31
  • Also, this general method will fail if daylight savings starts between the two dates, because there'll be a day with only 23 hours, which messes up the division. – Dawood ibn Kareem Oct 12 '17 at 19:32
  • Note that `Calendar` and `Date` classes, which are part of the old date API, are legacy now. Instead use classes of the new API inside the package `java.time`. – Zabuzard Oct 12 '17 at 19:38
  • Thanks, I put the milliseconds and it worked, I won't have issues with daylight savings because my country does not use them – zepol Oct 12 '17 at 19:41
  • @Alex Just because your country doesn't have daylight saving now, it doesn't mean it'll never have. DST is decided by governments and laws, and you can't guarantee that nobody will change this in the future. Anyway, if you just care about the dates without consider the time of the day, nor any DST effects, Szymon's solution with `LocalDate` works fine. But if you want to consider time of the day and DST, there's plenty of options in the possible duplicate I linked - specially [this](https://stackoverflow.com/a/23185006/7605325) with `ZonedDateTime` –  Oct 12 '17 at 22:08

1 Answers1

4

You can use java.time components if you use Java 8

import java.time.LocalDate;
import java.time.temporal.ChronoUnit;

final class PeriodTest {

    public static void main(String[] args) {
        LocalDate now = LocalDate.of(2017, 4, 4); // 2017-04-04
        LocalDate otherDate = LocalDate.of(2015, 10, 23); // 23-10-2015
        long days = Math.abs(ChronoUnit.DAYS.between(otherDate, now));

        System.out.println("Days = " + days);
    }
}

Output

Days = 529

Pros:

  • you don't have to play with old Calendar object
  • you can convert java.util.Date to java.time.Instant with Date.toInstant() method to get it working with current example

Java 6 solution

For Java 6 you can use Joda-Time that was a precursor of Java 8 Time API.

import org.joda.time.Days;
import org.joda.time.LocalDate;

final class PeriodTest {

    public static void main(String[] args) {
        LocalDate now = LocalDate.parse("2017-04-04");
        LocalDate otherDate = LocalDate.parse("2015-10-23");

        int days = Math.abs(Days.daysBetween(now, otherDate).getDays());

        System.out.println("Days = " + days);
    }
}
Szymon Stepniak
  • 40,216
  • 10
  • 104
  • 131
  • "the date as parameter is load from a database" –  Oct 12 '17 at 19:39
  • @Arkadiy `java.util.Date` can be converted to `java.time.Instant` easily with `Date.toInstant()` method. – Szymon Stepniak Oct 12 '17 at 19:40
  • Could you show the code to be used for the date represented by a `Date` object, then? OP: " if I tried with a main setting both dates it works" –  Oct 12 '17 at 19:41
  • Thank you so much, I've used this previously but unfortunately this app works with Java 6, and it's restricted with external libraries, so only working with I have – zepol Oct 12 '17 at 19:42
  • @Arkadiy Added an example using `java.util.Date` – Szymon Stepniak Oct 12 '17 at 19:46
  • @Alex You can use `Joda-Time` then. It works with Java 6 and it was a precursor for Java 8 Time API – Szymon Stepniak Oct 12 '17 at 19:47
  • @Alex I've added an example using Joda-Time and no Java 8 Time API – Szymon Stepniak Oct 12 '17 at 19:51
  • Your edit broke this. When you had `LocalDateTime`, this was correct, and handled daylight savings correctly. When you changed it to `Date`, you made the daylight savings handling wrong. I have removed my upvote. – Dawood ibn Kareem Oct 12 '17 at 19:59
  • @DawoodibnKareem Thanks for the comment, I haven't know that. The only problem is that Alex cannot use Java 8 solution anyway :/ – Szymon Stepniak Oct 12 '17 at 20:02
  • Sure, but I'm thinking of people who encounter this question in the future, not just Alex. Both your solutions are currently wrong. If you're offering a Java 8 solution, I recommend making it an entirely Java 8 solution, including the use of `LocalDate`. I don't know how to do this in joda-time, but I presume it must have something similar to `LocalDate` that you can use. – Dawood ibn Kareem Oct 12 '17 at 20:04
  • @DawoodibnKareem You're right. I've reverted code example to `LocalDate`, same with `Joda-Time`. Alex could also try to replace `java.util.Date` with `Joda-Time` to avoid many problems. – Szymon Stepniak Oct 12 '17 at 20:11
  • Cool. I've given you back my upvote. – Dawood ibn Kareem Oct 12 '17 at 20:25
  • For Java 6 and 7 you can use the [Threeten backport](http://www.threeten.org/threetenbp), a great backport for Java 8 new datetime API. Joda-Time is in maintainance mode and even in [their site](http://www.joda.org/joda-time) there's a warning: *Note that Joda-Time is considered to be a largely "finished" project. No major enhancements are planned. If using Java SE 8, please migrate to `java.time` (JSR-310)*. So, for new projects, it's better to use the backport. –  Oct 12 '17 at 21:55