36

I have written the following code to find days between two dates

    startDateValue = new Date(startDate);
    endDateValue = new Date(endDate);
    long diff = endDateValue.getTime() - startDateValue.getTime();
    long seconds = diff / 1000;
    long minutes = seconds / 60;
    long hours = minutes / 60;
    long days = (hours / 24) + 1;
    Log.d("days", "" + days);

When start and end date are 2/3/2017 and 3/3/2017 respectively the number of days showing is 29.Though when they are of the same day it is showing 1.(The number of days one takes a leave.So if one takes a single day leave,he has to select same start and end date.So in this case he has taken two days leave).

What am I doing wrong? Thank you for your time.

Note: Please don't use the date constructor. Check the accepted answer below. Use simpledateformat or Joda time. Date constructor is deprecated.

William Hu
  • 15,423
  • 11
  • 100
  • 121
debo.stackoverflow
  • 911
  • 1
  • 10
  • 30
  • 2
    What are `startDate` and `endDate`, exactly? (We don't even know their types at the moment.) If you could use Joda Time instead, that would be a *lot* better, btw. – Jon Skeet Mar 02 '17 at 10:39
  • @JonSkeet startDate = (string)2/3/2017 endDate = (string)3/3/2017 – debo.stackoverflow Mar 02 '17 at 10:50
  • So you're using the deprecated `Date(String)` constructor? I'd stop doing that, to start with. I'd suggest using `SimpleDateFormat` with a specific format and using the UTC time zone. (It may well be that you're getting the wrong result because of a DST transition - it's hard to know without knowing which time zone you're in.) – Jon Skeet Mar 02 '17 at 10:57
  • @JonSkeet Ok I have implemented Sachin answer which uses the Simple date Format.From now on will not use Date constructor. – debo.stackoverflow Mar 02 '17 at 11:14
  • 1
    Glad to hear it. That constructor was deprecated over 20 years ago :) – Jon Skeet Mar 02 '17 at 11:14
  • @JonSkeet :) Thanks – debo.stackoverflow Mar 02 '17 at 11:16
  • 3
    FYI, the troublesome old date-time classes such as [`java.util.Date`](https://docs.oracle.com/javase/9/docs/api/java/util/Date.html), `java.util.Calendar` and `java.text.SimpleDateFormat` are now [legacy](https://en.wikipedia.org/wiki/Legacy_system), supplanted by the [java.time](https://docs.oracle.com/javase/9/docs/api/java/time/package-summary.html) classes built into Java 8 & Java 9. See [Tutorial by Oracle](https://docs.oracle.com/javase/tutorial/datetime/TOC.html). **See the [modern Answer by Anton Balaniuc](https://stackoverflow.com/a/42553293/642706).** – Basil Bourque Feb 10 '18 at 03:20
  • follow the below link it will work for u.the easy way https://stackoverflow.com/a/51244555/5697474 – Syed Danish Haider Jul 09 '18 at 11:34
  • You should try this https://stackoverflow.com/a/68997515/15005298 – Yaqoob Bhatti Aug 31 '21 at 11:12

17 Answers17

68

Your code for generating date object:

Date date = new Date("2/3/2017"); //deprecated

You are getting 28 days as answer because according to Date(String) constructor it is thinking day = 3,month = 2 and year = 2017

You can convert String to Date as follows:

String dateStr = "2/3/2017";
SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");
Date date = sdf.parse(dateStr);

Use above template to make your Date object. Then use below code for calculating days in between two dates. Hope this clear the thing.

It can de done as follows:

long diff = endDateValue.getTime() - startDateValue.getTime();
System.out.println ("Days: " + TimeUnit.DAYS.convert(diff, TimeUnit.MILLISECONDS));

Please check link

If you use Joda Time it is much more simple:

int days = Days.daysBetween(date1, date2).getDays();

Please check JodaTime

How to use JodaTime in Java Project

Community
  • 1
  • 1
SachinSarawgi
  • 2,632
  • 20
  • 28
30

Kotlin

Here is the example to calculate days from today to some date:

 val millionSeconds = yourDate.time - Calendar.getInstance().timeInMillis
 leftDays.text = TimeUnit.MILLISECONDS.toDays(millionSeconds).toString() + "days"

If you want to calculate two days, then change:

val millionSeconds = yourDate1.time - yourDate2.time

should work.

William Hu
  • 15,423
  • 11
  • 100
  • 121
15
public static int getDaysDifference(Date fromDate,Date toDate)
{
if(fromDate==null||toDate==null)
return 0;

return (int)( (toDate.getTime() - fromDate.getTime()) / (1000 * 60 * 60 * 24));
}
Jitendra virani
  • 366
  • 4
  • 8
10

Does Android fully support java-8? If yes you can simple use ChronoUnit class

LocalDate start = LocalDate.of(2017,2,3);
LocalDate end = LocalDate.of(2017,3,3);

System.out.println(ChronoUnit.DAYS.between(start, end)); // 28

or same thing using formatter

DateTimeFormatter formatter = DateTimeFormatter.ofPattern("M/d/yyyy");
LocalDate start = LocalDate.parse("2/3/2017",formatter);
LocalDate end = LocalDate.parse("3/3/2017",formatter);

System.out.println(ChronoUnit.DAYS.between(start, end)); // 28
Anton Balaniuc
  • 10,889
  • 1
  • 35
  • 53
  • 2
    No not available on Android. – Meno Hochschild Mar 02 '17 at 11:40
  • 1
    FYI, the troublesome old date-time classes such as `java.util.Date`, `java.util.Calendar`, and `java.text.SimpleDateFormat` are now legacy, supplanted by the [java.time](https://docs.oracle.com/javase/9/docs/api/java/time/package-summary.html) classes. Much of the *java.time* functionality is back-ported to Java 6 & Java 7 in the [***ThreeTen-Backport***](http://www.threeten.org/threetenbp/) project. Further adapted for earlier Android in the [***ThreeTenABP***](https://github.com/JakeWharton/ThreeTenABP) project. See [*How to use ThreeTenABP…*](http://stackoverflow.com/q/38922754/642706). – Basil Bourque Feb 10 '18 at 03:22
  • Built-in since Android API level 26. For lower API levels available through the backport, [ThreeTenABP](https://github.com/JakeWharton/ThreeTenABP), see [How to use ThreeTenABP in Android Project](https://stackoverflow.com/questions/38922754/how-to-use-threetenabp-in-android-project). – Ole V.V. Mar 31 '20 at 18:58
  • 2
    I can confirm this is now available on Android, *even for less than API 26*. Instead of using the otherwise excellent ThreeTenABP, you just need to use Android 4.0 and add in some simple config: https://developer.android.com/studio/preview/features#j8-desugar – 7200rpm Apr 22 '20 at 03:19
6

java.time and ThreeTenABP

If I understand correctly, you want the number of days from start day through end date inclusive.

    DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("d/M/u");

    String startDate = "2/3/2017";
    String endDate = "3/3/2017";

    LocalDate startDateValue = LocalDate.parse(startDate, dateFormatter);
    LocalDate endDateValue = LocalDate.parse(endDate, dateFormatter);
    long days = ChronoUnit.DAYS.between(startDateValue, endDateValue) + 1;

    System.out.println("Days: " + days);

Output:

Days: 2

ChronoUnit.DAYS.between() gives us a count of days from start date inclusive to end date exclusive. So to include the end date too we needed to add 1 day just as you did in the question.

What went wrong in your code?

You are using the Date(String) constructor. This constructor has been deprecated since 1997 because it works unreliably across time zones, so don’t use it. Also it’s kind of magical: at least I never really know what I get. Apparently it takes 2/3/2017 to mean February 3, 2017, where you intended 2 March 2017. From February 3 to March 3 inclusive is 29 days (since 2017 wasn’t a leap year). This explains why you got 29. (If necessary, we could spell our way through the documentation and find out why 2/3/2017 is interpreted the way it is, only I’d find that a pointless waste of time to do.)

You can’t convert from milliseconds. Please also note that not only the question but also the very many answers that convert from milliseconds to days are incorrect. Such a conversion assumes that a day is always 24 hours. Because of summer time (DST) and other time anomalies a day is not always 24 hours. All of those answers will count a day too few for example if the leave crosses the spring gap or spring forward when summer time begins.

Question: Doesn’t java.time require Android API level 26?

java.time works nicely on both older and newer Android devices. It just requires at least Java 6.

  • In Java 8 and later and on newer Android devices (from API level 26) the modern API comes built-in.
  • In non-Android Java 6 and 7 get the ThreeTen Backport, the backport of the modern classes (ThreeTen for JSR 310; see the links at the bottom).
  • On (older) Android use the Android edition of ThreeTen Backport. It’s called ThreeTenABP. And make sure you import the date and time classes from org.threeten.bp with subpackages.

Links

Ole V.V.
  • 81,772
  • 15
  • 137
  • 161
5

What date format do you use? Is it d/M/yyyy or M/d/yyyy?

d = day, M = month, yyyy = year

(see: https://developer.android.com/reference/java/text/SimpleDateFormat.html)

Then the codes:

public static final String DATE_FORMAT = "d/M/yyyy";  //or use "M/d/yyyy"   

public static long getDaysBetweenDates(String start, String end) {
    SimpleDateFormat dateFormat = new SimpleDateFormat(DATE_FORMAT, Locale.ENGLISH);
    Date startDate, endDate;
    long numberOfDays = 0;
    try {
        startDate = dateFormat.parse(start);
        endDate = dateFormat.parse(end);
        numberOfDays = getUnitBetweenDates(startDate, endDate, TimeUnit.DAYS);
    } catch (ParseException e) {
        e.printStackTrace();
    }
    return numberOfDays;
}

And for getUnitBetweenDates method:

private static long getUnitBetweenDates(Date startDate, Date endDate, TimeUnit unit) {
    long timeDiff = endDate.getTime() - startDate.getTime();
    return unit.convert(timeDiff, TimeUnit.MILLISECONDS);
}
Janice Kartika
  • 502
  • 1
  • 3
  • 14
4

Very simple, just use Calendar, create two instances for the two dates, convert to milliseconds, subtract and convert to days (rounded up)... like this, basically:

Calendar startDate = Calendar.getInstance();
startDate.set(mStartYear, mStartMonth, mStartDay);
long startDateMillis = startDate.getTimeInMillis();

Calendar endDate = Calendar.getInstance();
endDate.set(mEndYear, mEndMonth, mEndDay);
long endDateMillis = endDate.getTimeInMillis();

long differenceMillis = endDateMillis - startDateMillis;
int daysDifference = (int) (differenceMillis / (1000 * 60 * 60 * 24));
fuzzKitty
  • 334
  • 3
  • 7
3

Have look at this code , this is helpful for me ,hope it will help you.

public String get_count_of_days(String Created_date_String, String Expire_date_String) {
SimpleDateFormat dateFormat = new SimpleDateFormat("dd/MM/yyyy", Locale.getDefault());

Date Created_convertedDate = null, Expire_CovertedDate = null, todayWithZeroTime = null;
try {
    Created_convertedDate = dateFormat.parse(Created_date_String);
    Expire_CovertedDate = dateFormat.parse(Expire_date_String);

    Date today = new Date();

    todayWithZeroTime = dateFormat.parse(dateFormat.format(today));
} catch (ParseException e) {
    e.printStackTrace();
}

int c_year = 0, c_month = 0, c_day = 0;

if (Created_convertedDate.after(todayWithZeroTime)) {
    Calendar c_cal = Calendar.getInstance();
    c_cal.setTime(Created_convertedDate);
    c_year = c_cal.get(Calendar.YEAR);
    c_month = c_cal.get(Calendar.MONTH);
    c_day = c_cal.get(Calendar.DAY_OF_MONTH);

} else {
    Calendar c_cal = Calendar.getInstance();
    c_cal.setTime(todayWithZeroTime);
    c_year = c_cal.get(Calendar.YEAR);
    c_month = c_cal.get(Calendar.MONTH);
    c_day = c_cal.get(Calendar.DAY_OF_MONTH);
}


/*Calendar today_cal = Calendar.getInstance();
int today_year = today_cal.get(Calendar.YEAR);
int today = today_cal.get(Calendar.MONTH);
int today_day = today_cal.get(Calendar.DAY_OF_MONTH);
*/

Calendar e_cal = Calendar.getInstance();
e_cal.setTime(Expire_CovertedDate);

int e_year = e_cal.get(Calendar.YEAR);
int e_month = e_cal.get(Calendar.MONTH);
int e_day = e_cal.get(Calendar.DAY_OF_MONTH);

Calendar date1 = Calendar.getInstance();
Calendar date2 = Calendar.getInstance();

date1.clear();
date1.set(c_year, c_month, c_day);
date2.clear();
date2.set(e_year, e_month, e_day);

long diff = date2.getTimeInMillis() - date1.getTimeInMillis();

float dayCount = (float) diff / (24 * 60 * 60 * 1000);

return ("" + (int) dayCount + " Days");

}

Mr. Mad
  • 1,230
  • 1
  • 14
  • 28
2

Be carefur if you'd like to use received integer e.g. to indicate specific day in custom calendar implementation. For example, I tried to go in m app from monthly calendar view to daily view and show daily content, by calculating dates from 1970-01-01 to selected one, and each 25-31th day of month shows me as one day earlier, because datesDifferenceInMillis / (24 * 60 * 60 * 1000); may return something like 17645,95833333333, and casting this to int you'll get value lower by 1. In this case correctly number of days you'll get by rounding received float by using NumberFormat class. Here's my code:

NumberFormat numberFormat = NumberFormat.getInstance(Locale.getDefault());
numberFormat.setRoundingMode(RoundingMode.HALF_UP);
numberFormat.setMaximumFractionDigits(0);
numberFormat.setMinimumFractionDigits(0);
int days = numberFormat.parse(numberFormat.format(value)).intValue();

I hope it will be helpful.

grabarz121
  • 616
  • 5
  • 13
  • 3
    Days are not always 24 hours long, so this is not accurate. Much easier to use `ChronoUnit.DAYS.between( start , stop )`. – Basil Bourque Feb 09 '18 at 17:16
1

I modified Jitendra's answer in Kotlin:

fun getDaysBetweenDates(firstDateValue: String, secondDateValue: String, format: String): String
{
    val sdf = SimpleDateFormat(format, Locale.getDefault())

    val firstDate = sdf.parse(firstDateValue)
    val secondDate = sdf.parse(secondDateValue)

    if (firstDate == null || secondDate == null)
        return 0.toString()

    return (((secondDate.time - firstDate.time) / (1000 * 60 * 60 * 24)) + 1).toString()
}

and call it like

val days = getDaysBetweenDates("31-03-2020", "24-04-2020","dd-MM-yyyy")
MaKi
  • 263
  • 5
  • 11
  • 1
    Please don’t teach the young ones to use the long outdated and notoriously troublesome `SimpleDateFormat` class. At least not as the first option. And not without any reservation. Today we have so much better in [`java.time`, the modern Java date and time API,](https://docs.oracle.com/javase/tutorial/datetime/) and its `DateTimeFormatter`. Yes, you can use it on Android. For older Android see [How to use ThreeTenABP in Android Project](https://stackoverflow.com/questions/38922754/how-to-use-threetenabp-in-android-project). – Ole V.V. Mar 31 '20 at 18:20
1
fun countDaysBetweenTwoCalendar(calendarStart: Calendar, calendarEnd: Calendar) : Int{
    val millionSeconds = calendarEnd.timeInMillis - calendarStart.timeInMillis
    val days = TimeUnit.MILLISECONDS.toDays(millionSeconds) //this way not round number
    val daysRounded = (millionSeconds / (1000.0 * 60 * 60 * 24)).roundToInt()
    return daysRounded
}
Denis
  • 11
  • 2
  • 1
    Welcome to StackOverflow! Please, provide an explanation in order to improve your answer and make it more understandable for the community – xKobalt Aug 21 '20 at 11:05
1

while none of these worked for me, here is an easy way to implement your code with a very simple fonction :

private long getDaysDifference(Date fromDate,Date toDate) {

    if(fromDate == null || toDate == null)
        return 0;


    int a = Integer.parseInt(DateFormat.format("dd",   fromDate)+"");
    int b = Integer.parseInt(DateFormat.format("dd",   toDate)+"");

    if ( b <= a){
        return Calendar.getInstance().getActualMaximum(Calendar.DAY_OF_MONTH) + b - a;
    }
    return b - a;
}

EnJoY

Arnaud
  • 408
  • 4
  • 11
1

SUPER SIMPLE

use LocalDate() include implementation 'com.jakewharton.threetenabp:threetenabp:1.2.1' to use in android

Example

IN KOTLIN

val daysDifferene = LocalDate.of(2017,3,3).toEpochDay() - LocalDate.of(2017,3,2)

even better

create extension function to LocalDate class

private operator fun LocalDate.minus(other: LocalDate) = toEpochDay() - other.toEpochDay()
  

now just say

val daysDifference = localDate1 - localDate2 // you get number of days in Long type

IN JAVA

long daysDifference = LocalDate.of(2017,3,3).toEpochDay() - LocalDate.of(2107,3,2) 
Abhinav Chauhan
  • 1,304
  • 1
  • 7
  • 24
0

You can use joda time, it so simple

fun getBetweenDates(startDate: Long, endDate: Long): String {
    val period = Period(startDate, endDate, PeriodType.yearMonthDayTime())

    val formatter = PeriodFormatterBuilder()
        .appendYears().appendSuffix(" year ")
        .appendMonths().appendSuffix(" month ")
        .appendDays().appendSuffix(" days ")
        .appendHours().appendSuffix(" hours ")
        .appendMinutes().appendSuffix(" minutes ")
        .appendSeconds().appendSuffix(" seconds ")
        .appendMillis().appendSuffix(" millis ")
        .toFormatter()

    return formatter.print(period)
}

start and end dates millisecond, and result example: "2 year 1 month ..."

semih
  • 821
  • 8
  • 16
  • FYI, the *Joda-Time* project has been supplanted by its official successor: The *java.time* classes built into Java 8 and later, defined in JSR 310. – Basil Bourque Jan 30 '23 at 21:58
0

use this way :

 fun stringDateToCalendar(dateString: String?, formatString: String): Calendar? {

        if (dateString == null || dateString.isEmpty() || formatString.isBlank())
            return null

        val inputDateFormat = SimpleDateFormat(formatString, Locale.ENGLISH)

        return try {
            inputDateFormat.parse(dateString)?.let {
                val cal = Calendar.getInstance()
                cal.time = it
                cal
            }
        } catch (e: ParseException) {
            null
        }

 }
    
 val calendarFrom = stringDateToCalendar(
      "2021-12-12",
      "yyyy-MM-dd"
 )

 val calendarTo = CalendarUtils.stringDateToCalendar(
      "2022-03-20",
      "yyyy-MM-dd"
 )
    
    

 val msDiff = calendarTo?.timeInMillis?.minus(calendarFrom?.timeInMillis ?: 0) ?: 0
 val daysDiff = TimeUnit.MILLISECONDS.toDays(msDiff)
Rasoul Miri
  • 11,234
  • 1
  • 68
  • 78
0

Here the simply common function Kotlin code

Here comparing these formatted dates "2022-11-04", "2022-11-20" Output will be 16 Days

 open fun dateSubstraction(date1: String, date2: String): String {
        val dateFormatter = SimpleDateFormat("yyyy-MM-dd") //Define input date format here
        val formatedDate1= dateFormat.parse(date1)  //formated  date1
        val formatedDate2= dateFormat.parse(date2)  //formated date2
        val millionSeconds = formatedDate2.time - formatedDate1.time
        return TimeUnit.MILLISECONDS.toDays(millionSeconds).toString()+"Days"
    }
Rahul Raj
  • 1,010
  • 9
  • 10
  • (1) Consider not using `SimpleDateFormat` and `Date` since they are troublesome and outdated. Use java.time, the modern Java date and time API. Through desugaring if needed. (2) `TimeUnit.MILLISECONDS.toDays()` assumes a day is always 24 hours. It isn’t always, so in corner cases you will get a day too few. – Ole V.V. Nov 03 '22 at 08:59
0

I have done this work in past. This was very simple

 val currentCalendar = Calendar.getInstance()
    val targetCalendar = Calendar.getInstance().apply {
        set(2023, Calendar.APRIL, 9, 23, 59, 59)
    }//your input: date, month, and time
    val difference = targetCalendar.timeInMillis - currentCalendar.timeInMillis
    val differenceInDays = TimeUnit.MILLISECONDS.toDays(difference)
    val remainingMonths = differenceInDays / 30//remaining months
    val remainingDays = differenceInDays % 30//remaining days
    val differenceInSeconds = TimeUnit.MILLISECONDS.toSeconds(difference)
    val differenceInMinutes = TimeUnit.MILLISECONDS.toMinutes(difference)
    val differenceInHours = TimeUnit.MILLISECONDS.toHours(difference)
    val remainingSeconds = differenceInSeconds % 60//remaining seconds
    val remainingMinutes = differenceInMinutes % 60//remaining minutes
    val remainingHours = differenceInHours % 24// remaining hours

Thats It We have done it

  • 2
    Very simple? In comparison to the one-liner in [the answer by Anton Balaniuc](https://stackoverflow.com/a/42553293/5772882)? I keep recommending not to use `Calendar`. It’s cumbersome to work with and long outdated. [java.time, the modern Java date and time API](https://docs.oracle.com/javase/tutorial/datetime/index.html) makes the task a lot easier. – Ole V.V. Jan 30 '23 at 15:56
  • 1
    Also your code is not correct. `TimeUnit.MILLISECONDS.toDays()` assumes that a day is always 24 hours, but that is not the case. And a month isn’t always 30 days (in fact more often 31). – Ole V.V. Jan 30 '23 at 15:58