Date Difference in Human Readable format in Java Date Difference in Human Readable format in Java

Page content

In this quick tutorial, we’ll learn how to print the difference between two dates in human readable format in Java.

Requirement

We want to create a utility method in Java which returns the difference between two Dates in human readable format i.e. in Years, Months, and Days.

These are few examples of expected difference between two dates:-

Start DateEnd DateExpected Difference
2000-01-012001-01-011 Year
2000-01-012020-01-0120 Years
2000-01-012000-02-011 Month
2000-01-012000-11-0110 Months
2000-01-012000-01-021 Day
2000-01-012000-01-2625 Days
2000-01-012001-02-021 Year, 1 Month and 1 Day
2000-01-012005-05-045 Years, 4 Months and 3 Days
2000-01-012001-01-261 Year and 25 Days
2000-01-012000-05-044 Months and 3 Days

Let’s build a utility method to achieve this.

Date Utlity Method

Let’s create a utility method DateUtils.getDiffInHumanReadableFormat(startDate, endDate) to find the difference between two LocalDate in human readable format i.e. in Years, Months, and Days.

package com.example.util;

import java.time.LocalDate;
import java.time.Period;

public class DateUtils {

  public static String getDiffInHumanReadableFormat(LocalDate startDate, LocalDate endDate) {
    Period period = Period.between(startDate, endDate);
    StringBuilder token = new StringBuilder();
    appendUnits(token, period.getYears(), "Year");
    yearSeparator(period, token);
    appendUnits(token, period.getMonths(), "Month");
    monthSeparator(period, token);
    appendUnits(token, period.getDays(), "Day");
    return token.toString().trim();
  }

  // Helper Methods

  private static void appendUnits(StringBuilder token, int units, String unitName) {
    if (units > 0) {
      token.append(units).append(" ").append(unitName);
      if (units > 1) token.append("s");
    }
  }

  private static void yearSeparator(Period period, StringBuilder token) {
    if (period.getYears() > 0 && period.getMonths() > 0) {
      token.append(period.getDays() > 0 ? ", " : " and ");
    }
  }

  private static void monthSeparator(Period period, StringBuilder token) {
    boolean appendAnd = (period.getMonths() > 0 && period.getDays() > 0) ||
            (period.getMonths() == 0 && period.getYears() > 0 && period.getDays() > 0);
    if (appendAnd) token.append(" and ");
  }
}

Let’s write a test case to validate our method:-

package com.example.util;

import org.junit.jupiter.api.Test;
import java.time.LocalDate;
import static org.junit.jupiter.api.Assertions.assertEquals;

public class DateUtilsTest {

  @Test
  void testGetHumanReadableDiff() {
    assertEquals("1 Year",
            DateUtils.getDiffInHumanReadableFormat(LocalDate.of(2000, 1, 1), LocalDate.of(2001, 1, 1)));
    assertEquals("20 Years",
            DateUtils.getDiffInHumanReadableFormat(LocalDate.of(2000, 1, 1), LocalDate.of(2020, 1, 1)));
    assertEquals("1 Month",
            DateUtils.getDiffInHumanReadableFormat(LocalDate.of(2000, 1, 1), LocalDate.of(2000, 2, 1)));
    assertEquals("10 Months",
            DateUtils.getDiffInHumanReadableFormat(LocalDate.of(2000, 1, 1), LocalDate.of(2000, 11, 1)));
    assertEquals("1 Day",
            DateUtils.getDiffInHumanReadableFormat(LocalDate.of(2000, 1, 1), LocalDate.of(2000, 1, 2)));
    assertEquals("25 Days",
            DateUtils.getDiffInHumanReadableFormat(LocalDate.of(2000, 1, 1), LocalDate.of(2000, 1, 26)));
    assertEquals("1 Year, 1 Month and 1 Day",
            DateUtils.getDiffInHumanReadableFormat(LocalDate.of(2000, 1, 1), LocalDate.of(2001, 2, 2)));
    assertEquals("5 Years, 4 Months and 3 Days",
            DateUtils.getDiffInHumanReadableFormat(LocalDate.of(2000, 1, 1), LocalDate.of(2005, 5, 4)));
    assertEquals("5 Years and 4 Months",
            DateUtils.getDiffInHumanReadableFormat(LocalDate.of(2000, 1, 1), LocalDate.of(2005, 5, 1)));
    assertEquals("1 Year and 25 Days",
            DateUtils.getDiffInHumanReadableFormat(LocalDate.of(2000, 1, 1), LocalDate.of(2001, 1, 26)));
    assertEquals("4 Months and 3 Days",
            DateUtils.getDiffInHumanReadableFormat(LocalDate.of(2000, 1, 1), LocalDate.of(2000, 5, 4)));
  }
}

That’s it! You can copy the code and use. Thanks for reading!