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!