0

I'm trying to count the days between two dates but I can't get a right result. I did the same that someone described to me.

My result should be an int or long. For this example I would expext 11 but 10 is also fine.

That's the code:

String startDate = "2018-03-25";
String endDate = "2018-04-05";
Date startDate1 = stringToDate(startDate);
Date endDate1 = stringToDate(endDate);

long ab = daysBetween(startDate1, endDate1);
String ab1 = String.valueOf(ab);

And that's the methods:

public static long daysBetween(Date startDate, Date endDate) {
    Calendar sDate = getDatePart(startDate);
    Calendar eDate = getDatePart(endDate);

    long daysBetween = 0;
    while (sDate.before(eDate)) {
        sDate.add(Calendar.DAY_OF_MONTH, 1);
        daysBetween++;
    }
    return daysBetween;
}

public Date stringToDate(String stringDatum) {
    SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");

    try {
        Date date = format.parse(stringDatum);
        return date;
    }
    catch (ParseException e) {
        e.printStackTrace();
    }
    return null;
}

public static Calendar getDatePart(Date date){
    Calendar cal = Calendar.getInstance();       // get calendar instance
    cal.setTime(date);
    cal.set(Calendar.HOUR_OF_DAY, 0);            // set hour to midnight
    cal.set(Calendar.MINUTE, 0);                 // set minute in hour
    cal.set(Calendar.SECOND, 0);                 // set second in minute
    cal.set(Calendar.MILLISECOND, 0);            // set millisecond in second

    return cal;                                   // return the date part
}
yoms
  • 58
  • 4
Sven
  • 31
  • 11
  • 1
    So what result *do* you get? What is `getDatePart`? Are you able to reproduce this in a [mcve] outside Android? (That would definitely make things simpler.) I'd also *strongly* recommend changing your exception handling to avoid swallowing exceptions like this. – Jon Skeet Mar 27 '18 at 17:27
  • the String ab1 its just for make a Toast in Android Studio. – Sven Mar 27 '18 at 17:29
  • That doesn't really explain what result you get. But I would strongly advise you to rewrite this as a console app in plain Java unless you believe that it's fundamentally a problem in the Android libraries. I believe there are far more people who can run a simple console app than will be willing to create a new Android project and take the necessary steps to run your code. – Jon Skeet Mar 27 '18 at 17:35
  • This post seems relevant https://stackoverflow.com/questions/428918/how-can-i-increment-a-date-by-one-day-in-java?utm_medium=organic&utm_source=google_rich_qa&utm_campaign=google_rich_qa – mm8511 Mar 27 '18 at 17:35
  • I am getting 11 as output from your code. Where is the problem ? As Jon said, simple console run – voucher_wolves Mar 27 '18 at 17:35
  • You should really be using a different time library nowadays. https://github.com/JakeWharton/ThreeTenABP – OneCricketeer Mar 27 '18 at 17:37
  • Think I might have figured out your problem. Try using int instead of long in your "daysBetween" method... updates (such as increment) on longs are not atomic, so you may be returning before your "daysBetween" variable is actually updated. (see: https://stackoverflow.com/questions/517532/writing-long-and-double-is-not-atomic-in-java/517539) – mm8511 Mar 27 '18 at 17:42
  • thank you all. Its solved. It was a problem with the datePicker. It gave me the wrong dates. – Sven Mar 28 '18 at 16:02

2 Answers2

4

java.util.Date, Calendar and SimpleDateFormat are part of a terrible API. They make the job of date/time handling harder than it already is.

Make yourself a favor and use a decent date/time library: https://github.com/JakeWharton/ThreeTenABP - here's a nice tutorial on how to use it - How to use ThreeTenABP in Android Project

With this API, it's so easy to do what you want:

LocalDate startDate = LocalDate.parse("2018-03-25");
LocalDate endDate = LocalDate.parse("2018-04-05");

long daysBetween = ChronoUnit.DAYS.between(startDate, endDate); // 11

I've chosen to use LocalDate based on your code: the inputs have only day, month and year, and you're setting the hour/minute/seconds to zero, so I understand that you don't care about the time of the day to calculate the difference - which makes LocalDate the best choice.

Date and Calendar represent a specific point in time, and Calendar also uses a timezone, so Daylight Saving changes might affect the results, depending on the device's default timezone. Using a LocalDate avoids this problem, because this class doesn't have a timezone.

But anyway, I've tested your code and also got 11 as result, so it's not clear what problems you're facing.

yoms
  • 58
  • 4
  • thank you. It's solved now. It was a problem with the datePicker. It gave me the wrong dates. Thank you for the new Date library – Sven Mar 28 '18 at 16:03
-2
private static long daysBetween(Date date1, Date date2){
    return (date2.getTime() - date1.getTime())  / (60*60*24*1000);
}
ykembayev
  • 108
  • 1
  • 8