M Ansyori
M Ansyori

Reputation: 488

Calculate Years and Months between Two Dates in Android

I am trying to display a custom text result between two dates. Here is the code in my Fragment, which return two dates:

public class HomeFragment extends BaseFragment {

  ...

  dashboardViewModel.productCategory.observe(this, data - > {
    if (data != null && data.getData() != null) {
      int totalLos = Integer.parseInt(data.getData().getLos());
      Log.e("totalLOS", String.valueOf(totalLos));
      explainDays(totalLos);
      mBinding.los.setText("");
    }
  });

}

And here the code in BaseFragment which generate two dates:

public abstract class BaseFragment extends Fragment {

  ...
  public void explainDays(int totalDays) {

    Calendar calendar = Calendar.getInstance();
    Date start = calendar.getTime();

    calendar.add(Calendar.DATE, -totalDays);
    Date end = calendar.getTime();

    Log.e("startDate", String.valueOf(start));
    Log.e("endDate", String.valueOf(end));

  }

}

From the code above, I am getting these three logs:

E/totalLOS: 1233
E/startDate: Mon Jun 08 19:45:08 GMT+07:00 2020
E/endDate: Sun Jan 22 19:45:08 GMT+07:00 2017

How do I generate a response like for example 1 Year and 5 Months since 2007 between these two date results? the since 2007 needs to be extracted from endDate from Log above.

Any help will be much appreciated.

Thank you.

Upvotes: 2

Views: 3474

Answers (3)

Abhay Pratap
Abhay Pratap

Reputation: 1986

// in kotlin 
fun getDateAndYearsDifference(startDate: Date?, endDate: Date? = null): String {
    val startCalendar: Calendar = GregorianCalendar()
    startCalendar.time = startDate
    val endCalendar: Calendar = GregorianCalendar()
    endCalendar.time = endDate ?: Calendar.getInstance().time
    val period = Period(startCalendar.time.time, endCalendar.time.time, PeriodType.standard())
    val yearsAndMonths = PeriodFormatterBuilder()
        .printZeroNever()
        .appendYears()
        .appendSuffix(" yrs", " yrs")
        .appendSeparator(Constants.COMMA)
        .printZeroRarelyLast()
        .appendMonths()
        .appendSuffix(" mos", " mos")
        .toFormatter()
    return period.toString(yearsAndMonths)
}

Upvotes: 0

Arvind Kumar Avinash
Arvind Kumar Avinash

Reputation: 79075

java.time

You can do it as follows:

import java.time.OffsetDateTime;
import java.time.Period;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;

public class Main {
    public static void main(String[] args) {
        // Define format
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("EEE MMM dd HH:mm:ss O yyyy");

        // Date/time strings
        String strEndDate = "Mon Jun 08 19:45:08 GMT+07:00 2020";
        String strStartDate = "Sun Jan 22 19:45:08 GMT+07:00 2017";

        // Define ZoneOffset
        ZoneOffset zoneOffset = ZoneOffset.ofHours(6);

        // Parse date/time strings into OffsetDateTime
        OffsetDateTime startDate = OffsetDateTime.parse(strStartDate, formatter).withOffsetSameLocal(zoneOffset);
        OffsetDateTime endDate = OffsetDateTime.parse(strEndDate, formatter).withOffsetSameLocal(zoneOffset);

        // Calculate period between `startDate` and `endDate`
        Period period = Period.between(startDate.toLocalDate(), endDate.toLocalDate());

        // Display result
        System.out.println(
                period.getYears() + " years and " + period.getMonths() + " months since " + startDate.getYear());
    }
}

Output:

3 years and 4 months since 2017

Note: Instead of using the outdated java.util.Date and SimpleDateFormat, use the modern date/time API. Check this to learn more about it.


Note: The following content has been copied from How to get start time and end time of a day in another timezone in Android

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.

But don't we have any other option apart from switching to ThreeTenBP Library?

If you insisted, I suppose that a way through using Calendar, Date and SimpleDateFormat could be found. Those classes are poorly designed and long outdated, so with what I know and don’t know I would prefer ThreeTenABP.

Links


Upvotes: 4

Prathamesh
Prathamesh

Reputation: 1057

If you can extract the month,day and year from both dates you can use following solution to calculate the exact difference between two dates.

            int sday=22 //int day of month here
            int smonth=1 //int month here
            int syear=2017 //int year here

            int eday=5 //int day of month here
            int emonth=6 //int month here
            int eyear=2020 //int year here

                resyear = eyear - syear;
                if (emonth >= smonth) {
                    resmonth = emonth - smonth;
                } else {
                    resmonth = emonth - smonth;
                    resmonth = 12 + resmonth;
                    resyear--;
                }
                if (eday >= sday) {
                    resday = eday - sday;
                } else {
                    resday = eday - sday;
                    resday = 31 + resday;
                    if (resmonth == 0) {
                        resmonth = 11;
                        resyear--;
                    } else {
                        resmonth--;
                    }
                }
                if (resday <0 || resmonth<0 || resyear<0) {
                    Toast.makeText(getApplicationContext(), "starting date must greater than ending date", Toast.LENGTH_LONG).show();

                }
                else {

Toast.makeText(getApplicationContext(), "difference: " + resyear + " years /" + resmonth + " months/" + resday + " days", Toast.LENGTH_LONG).show();

                }
            }

Upvotes: 0

Related Questions