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 that 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 Date End Date Expected Difference
2000-01-01 2001-01-01 1 Year
2000-01-01 2020-01-01 20 Years
2000-01-01 2000-02-01 1 Month
2000-01-01 2000-11-01 10 Months
2000-01-01 2000-01-02 1 Day
2000-01-01 2000-01-26 25 Days
2000-01-01 2001-02-02 1 Year, 1 Month and 1 Day
2000-01-01 2005-05-04 5 Years, 4 Months and 3 Days
2000-01-01 2001-01-26 1 Year and 25 Days
2000-01-01 2000-05-04 4 Months and 3 Days

Let’s build a utility method to achieve this.

Date Utility Method

Let’s create a Java 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 it. Thanks for reading!