How do I calculate difference between two dates?

In this example you’ll learn how to use the java.time.Period class (from Java 8) to calculate difference between two dates. Using Period.between() method will give us difference between two dates in years, months and days period.

Beside using the Period class, we also use the ChronoUnit enum to calculate difference between two dates. We use the ChronoUnit.YEARS, ChronoUnit.MONTHS and ChronoUnit.DAYS and call the between() method to get the difference between two dates in years, months and days.

Let’s see an example below.

package org.kodejava.datetime;

import java.time.LocalDate;
import java.time.Month;
import java.time.Period;
import java.time.temporal.ChronoUnit;

public class DateDifference {
    public static void main(String[] args) {
        LocalDate birthDate = LocalDate.of(1995, Month.AUGUST, 17);
        LocalDate now = LocalDate.now();

        // Obtains a period consisting of the number of years, months and days
        // between two dates.
        Period age = Period.between(birthDate, now);
        System.out.printf("You are now %d years, %d months and %d days old.%n",
                age.getYears(), age.getMonths(), age.getDays());

        // Using ChronoUnit to calculate difference in years, months and days
        // between two dates.
        long years = ChronoUnit.YEARS.between(birthDate, now);
        long months = ChronoUnit.MONTHS.between(birthDate, now);
        long days = ChronoUnit.DAYS.between(birthDate, now);

        System.out.println("Diff in years  = " + years);
        System.out.println("Diff in months = " + months);
        System.out.println("Diff in days   = " + days);
    }
}

The result of our code snippet above are:

You are now 26 years, 2 months and 30 days old.
Diff in years  = 26
Diff in months = 314
Diff in days   = 9588

How do I use the java.time.DayOfWeek enum?

The java.time.DayOfWeek enums in Java 8 Date-Time API describes the days of the week. The enum has constants value from DayOfWeek.MONDAY through DayOfWeek.SUNDAY. These enums also have their integer values where 1 is equal to MONDAY and 7 is equal to SUNDAY.

In the code snippet below you can see a couple usage of the DayOfWeek enums. We start by getting all the enum values using the values() method that return an array of DayOfWeek. We iterate this array and print out the enum value and its corresponding integer value.

// Get DayOfWeek enums value
DayOfWeek[] dayOfWeeks = DayOfWeek.values();
for (int i = 0; i < dayOfWeeks.length; i++) {
    DayOfWeek dayOfWeek = dayOfWeeks[i];
    System.out.println("dayOfWeek[" + i + "] = " + dayOfWeek + "; value = " +
            dayOfWeek.getValue());
}

To create a DayOfWeek object we can use the of(int) factory method. We pass an integer value of this method. For example giving 1 will give us the DayOfWeek.MONDAY. We can also utilize enum valueOf(String) method to create enum from string value.

// Get DayOfWeek from int value
DayOfWeek dayOfWeek = DayOfWeek.of(1);
System.out.println("dayOfWeek = " + dayOfWeek);

// Get DayOfWeek from string value
dayOfWeek = DayOfWeek.valueOf("SATURDAY");
System.out.println("dayOfWeek = " + dayOfWeek);

To get the DayOfWeek from a date-time object we can use the getDayOfWeek() method. Below we get the day of week from a LocalDate object.

// Get DayOfWeek of a date object
LocalDate date = LocalDate.now();
DayOfWeek dow = date.getDayOfWeek();

System.out.println("Date  = " + date);
System.out.println("Dow   = " + dow + "; value = " + dow.getValue());

We can also get the day of week for a specific locale. To do this we can use the DayOfWeek.getDisplayName(TextStyle, Locale) method. The TextStyle can be of value TextStyle.FULL, TextStyle.SHORT, TextStyle.NARROW which will give us the full, short, and narrow version of the display name. The example below get the display name for Indonesian and German version.

// Get DayOfWeek display name in different locale.
Locale locale = new Locale("id", "ID");
String indonesian = dow.getDisplayName(TextStyle.SHORT, locale);
System.out.println("ID = " + indonesian);

String germany = dow.getDisplayName(TextStyle.FULL, Locale.GERMANY);
System.out.println("DE = " + germany);

There is also a plus(long) method that can be used to add number of days to a DayOfWeek object. For example adding 4 to MONDAY will give us DayOfWeek.FRIDAY.

// Adding number of days to DayOfWeek enum.
System.out.println("DayOfWeek.MONDAY.plus(4) = " + DayOfWeek.MONDAY.plus(4));

Here is the complete code for the snippets above:

package org.kodejava.datetime;

import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.format.TextStyle;
import java.util.Locale;

public class DayOffWeekExample {
    public static void main(String[] args) {
        // Get DayOfWeek enums value
        DayOfWeek[] dayOfWeeks = DayOfWeek.values();
        for (int i = 0; i < dayOfWeeks.length; i++) {
            DayOfWeek dayOfWeek = dayOfWeeks[i];
            System.out.println("dayOfWeek[" + i + "] = " + dayOfWeek + "; value = " +
                    dayOfWeek.getValue());
        }

        // Get DayOfWeek from int value
        DayOfWeek dayOfWeek = DayOfWeek.of(1);
        System.out.println("dayOfWeek = " + dayOfWeek);

        // Get DayOfWeek from string value
        dayOfWeek = DayOfWeek.valueOf("SATURDAY");
        System.out.println("dayOfWeek = " + dayOfWeek);

        // Get DayOfWeek of a date object
        LocalDate date = LocalDate.now();
        DayOfWeek dow = date.getDayOfWeek();

        System.out.println("Date  = " + date);
        System.out.println("Dow   = " + dow + "; value = " + dow.getValue());

        // Get DayOfWeek display name in different locale.
        Locale locale = new Locale("id", "ID");
        String indonesian = dow.getDisplayName(TextStyle.SHORT, locale);
        System.out.println("ID = " + indonesian);

        String germany = dow.getDisplayName(TextStyle.FULL, Locale.GERMANY);
        System.out.println("DE = " + germany);

        // Adding number of days to DayOfWeek enum.
        System.out.println("DayOfWeek.MONDAY.plus(4) = " + DayOfWeek.MONDAY.plus(4));
    }
}

And the result of the code above are:

dayOfWeek[0] = MONDAY; value = 1
dayOfWeek[1] = TUESDAY; value = 2
dayOfWeek[2] = WEDNESDAY; value = 3
dayOfWeek[3] = THURSDAY; value = 4
dayOfWeek[4] = FRIDAY; value = 5
dayOfWeek[5] = SATURDAY; value = 6
dayOfWeek[6] = SUNDAY; value = 7
dayOfWeek = MONDAY
dayOfWeek = SATURDAY
Date  = 2021-11-16
Dow   = TUESDAY; value = 2
ID = Sel
DE = Dienstag
DayOfWeek.MONDAY.plus(4) = FRIDAY

How do I format date-time objects in Java 8?

In your Java application you want to format date-time objects using the new date and time API introduced in JDK 8. A solution to this problem is to use the java.time.format.DateTimeFormatter. The DateTimeFormatter class provides formatter for printing and parsing date-time objects.

With this class we can format the date-time objects using a predefined constants, there are many predefined ready to use formats, such as ISO_DATE, ISO_DATE_TIME. You can also use letters pattern to format the date-time objects, for instance using the dd MMMM yyyy. The formatter can format in localized style, in a long or medium style.

Let’s see an example below:

package org.kodejava.datetime;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Locale;

public class DateTimeFormatterDemo {
    public static void main(String[] args) {
        // Get system current date and time.
        LocalDateTime time = LocalDateTime.now();

        // Get an instance of DateTimeFormatter and print a
        // formatted version of the system current date-time
        // using a predefined formatter.
        DateTimeFormatter format = DateTimeFormatter.ISO_DATE_TIME;
        System.out.printf("Time: %s%n", time.format(format));

        // Create a custom formatter and format the date-time
        // object.
        DateTimeFormatter customFormat =
                DateTimeFormatter.ofPattern("MMMM d, yyyy hh:mm a");
        System.out.printf("Time: %s%n", time.format(customFormat));

        // Create a custom formatter with locale and format the
        // date-time object.
        DateTimeFormatter localeFormat =
                DateTimeFormatter.ofPattern("d MMM yyyy HH:mm:ss",
                        Locale.FRENCH);
        System.out.printf("Time: %s%n", time.format(localeFormat));
    }
}

The results of the code above are:

Time: 2021-11-16T07:51:16.1247212
Time: November 16, 2021 07:51 AM
Time: 16 nov. 2021 07:51:16

How do I get the length of month represented by a date object?

The following example show you how to get the length of a month represented by a java.time.LocalDate and a java.time.YearMonth objects. Both of these classes have a method called lengthOfMonth() that returns the length of month in days represented by those date objects.

package org.kodejava.datetime;

import java.time.LocalDate;
import java.time.Month;
import java.time.YearMonth;

public class LengthOfMonth {
    public static void main(String[] args) {
        // Get the length of month of the current date.
        LocalDate date = LocalDate.now();
        System.out.printf("%s: %d%n%n", date, date.lengthOfMonth());

        // Get the length of month of a year-month combination value
        // represented by the YearMonth object.
        YearMonth yearMonth = YearMonth.of(2020, Month.FEBRUARY);
        System.out.printf("%s: %d%n%n", yearMonth, yearMonth.lengthOfMonth());

        // Repeat a process the get the length of a month for one-year
        // period.
        for (int month = 1; month <= 12; month++) {
            yearMonth = YearMonth.of(2021, Month.of(month));
            System.out.printf("%s: %d%n", yearMonth, yearMonth.lengthOfMonth());
        }
    }
}

The main() method above start by showing you how to get the month length of a LocalDate object. First we create a LocalDate object using the LocalDate.now() static factory method which return today’s date. And then we print out the length of month of today’s date on the following line.

The next snippet use the YearMonth class. We begin by creating a YearMonth object that represent the month of February 2020. We created it using the YearMonth.of() static factory method. We then print out the length of month for those year-month combination.

In the last lines of the example we create a for loop to get all month’s length for the year of 2021 from January to December.

And here are the result of our code snippet above:

2021-11-16: 30

2020-02: 29

2021-01: 31
2021-02: 28
2021-03: 31
2021-04: 30
2021-05: 31
2021-06: 30
2021-07: 31
2021-08: 31
2021-09: 30
2021-10: 31
2021-11: 30
2021-12: 31

How do I know if a given year is a leap year?

The example How do I check if a year is a leap year? use the java.util.Calendar object to determine if a given year is a leap year. That was the way to do it using the old API before we have the Date and Time API introduced in Java 8.

Now, in the Java 8 API we can check if a given year is a leap year using a couple of ways. We can determine if a given date is in a leap year by calling the isLeapYear() method of the java.time.LocalDate class. While using the java.time.Year class we can check is the given year if a leap year using the isLeap() method.

The following code snippet will show you how to do it:

package org.kodejava.datetime;

import java.time.LocalDate;
import java.time.Month;
import java.time.Year;
import java.time.temporal.ChronoField;

public class YearIsLeapExample {
    public static void main(String[] args) {
        // Using the java.time.LocalDate class.
        LocalDate now = LocalDate.now();
        boolean isLeap = now.isLeapYear();
        System.out.printf("Year %d, leap year = %s%n", now.getYear(), isLeap);

        LocalDate date = LocalDate.of(2020, Month.JANUARY, 1);
        isLeap = date.isLeapYear();
        System.out.printf("Year %d, leap year = %s%n", date.getYear(), isLeap);

        // Using the java.time.Year class.
        Year year = Year.now();
        isLeap = year.isLeap();
        System.out.printf("Year %d, leap year = %s%n", year.getValue(), isLeap);

        Year anotherYear = Year.of(2020);
        isLeap = anotherYear.isLeap();
        System.out.printf("Year %d, leap year = %s%n", anotherYear.get(ChronoField.YEAR), isLeap);
    }
}

The code snippet will print out the following result:

Year 2021, leap year = false
Year 2020, leap year = true
Year 2021, leap year = false
Year 2020, leap year = true