0

How can i get difference between two selected dates from calendar in Android in days, months and years ? We know all that the months sometimes have 30 days and sometimes 31 days and in February 28 days just every 4 years come 29 days. I want to get the result for example like this: 2 years and 6 months and 24 days. I try to use LocalDate so this is my code:

public void onSelectedDayChange(@NonNull CalendarView view,
        final int year, final int month, final int dayOfMonth) {

    textView.setText(String.valueOf(dateDiff(year,month,dayOfMonth)));
}

public Period dateDiff(int year,int month,int day){
    final int Day = c.get(Calendar.DAY_OF_MONTH);
    final int Month = c.get(Calendar.MONTH);
    final int Year = c.get(Calendar.YEAR);
    LocalDate localDate1 = LocalDate.of(year,month,day);
    LocalDate localDate2 = LocalDate.of(Year,Month,Day);

    Period period = Period.between(localDate2,localDate1);

    return period;
}

I tested the code but i got wrong result. When i test it with days (02/05/2020) i got 8 days but the difference is 7 days because "April" has 30 days and for the selected day (02/07/2020) i got 2 months and 8 days or the correct answer are 2 months and 7 days. I try to get first a correct result, if there is a function or a calculation formula to solve this wrong result, this will help me.

Finally i got in result each time something like (P2M8D) that's meaning 2 months and 8 days, or for example (P7D) that's mean 7 days, so how can i change this text to an understood one like 2 months and 8 days or 7 days like the 2 examples because i found problem in result because we have mixed between numbers and characters.

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

2 Answers2

1

You’re well on the right way.

  1. Follow the Java naming conventions. A variable or parameter name begins with a lower case letter. Always. It’s particularly confusing that you’ve got parameter year and variable Year. This is bound to lead to errors at some point (though this doesn’t seem to be the reason at the moment).
  2. Since you can use LocalDate and Period from java.time, the modern Java date and time API, don’t mix in the poorly designed and outdated Calendar class too, it just complicates things. Your use of LocalDate and Period is basically correct. For getting the current date as a LocalDate use LocalDate.now(ZoneId.systemDefault()) (and we no longer need the uppercase variables, two problems solved in one shot).
  3. I don’t know your date picker, but I suspect that it may use 0-based month numbers: 0 for January through 11 for December. If this is so, you need to add 1 to the month number when creating the LocalDate object.

For a more readable text use the methods of the Period object to get numbers and assemble your own string. A simple example is:

        String periodText = "" + period.getYears() + " years "
                    + period.getMonths() + " months " + period.getDays() + " days";

You will want to modify it to leave out the years if they are 0 and the months if they are 0. Consider what text you want to write if all the numbers are 0. You will want to write something, or the user will be confused. A further possible refinement will be to use singular of the words if there is exactly 1 (1 year rather than 1 years, etc.). You may look into using a StringJoiner and into writing an auxiliary method that returns a string with a number and the correct form of a noun, for example 1 month but 2 months.

Edit: Code for formatting the Period

Spelling out my suggestion in code, here’s a way to format your Period:

    StringJoiner joiner = new StringJoiner(" ");
    joiner.setEmptyValue("No time at all");
    if (period.getYears() != 0) {
        joiner.add(singularOrPlural(period.getYears(), "year", "years"));
    }
    if (period.getMonths() != 0) {
        joiner.add(singularOrPlural(period.getMonths(), "month", "months"));
    }
    if (period.getDays() != 0) {
        joiner.add(singularOrPlural(period.getDays(), "day", "days"));
    }
    String periodText = joiner.toString();

    System.out.println(periodText);

The code is using this auxiliary method:

private static String singularOrPlural(int count, String singular, String plural) {
    if (count == -1 || count == 1) {
        return "" + count + ' ' + singular;
    } else {
        return "" + count + ' ' + plural;
    }
}

Example outputs:

No time at all
1 day
2 days
1 month
1 month 1 day
2 months
3 years 4 months 5 days
-1 year -1 month -6 days
Ole V.V.
  • 81,772
  • 15
  • 137
  • 161
0

I can't understand the problem you have with the "wrong result" of the returned period, clarify it better to me if you can.

By the way, you can try this to convert a format like P2M8D to 2 months and 8 days:

public static void main(String[] args) {
    int year = 2020, month = 7, day = 2;
    int yearDiff = dateDiff(year, month, day).getYears();
    int monthDiff = dateDiff(year, month, day).getMonths();
    int dayDiff = dateDiff(year, month, day).getDays();
    System.out.println("Period -> yyyy:" + yearDiff + " mm:" + monthDiff + " dd:" + dayDiff); // OUTPUT: Period -> yyyy:0 mm:3 dd:7
}


static Period dateDiff(int year, int month, int day) {
    Calendar c = Calendar.getInstance();
    final int Day = c.get(Calendar.DAY_OF_MONTH);
    final int Month = c.get(Calendar.MONTH);
    final int Year = c.get(Calendar.YEAR);
    LocalDate localDate1 = LocalDate.of(year, month, day);
    LocalDate localDate2 = LocalDate.of(Year, Month, Day);

    return Period.between(localDate2, localDate1);
}

You have to use getDays, getMonths and getYears methods.

Alberto Ursino
  • 366
  • 3
  • 18
  • Thanks for your answer but i got in result each time 0 when i'm using the getDays, getMonths and getYears methods. Also the wrong result i talking about that every time when i select a date i got in my textView a wrong difference dates and i give in my question some exemple like P2M8D and this is the result i got in the text view – Mohamed Amine Sekmani Apr 25 '20 at 17:16
  • Can you let me see how have you initialize the variable c? – Alberto Ursino Apr 25 '20 at 21:01
  • Yes Alberto Ursino you are correct I named the variables of C like the name selected time I just change the firs letter with capital letter this made my project some problem. – Mohamed Amine Sekmani Apr 26 '20 at 17:19