I just announced the new Spring Boot 2 material, coming in REST With Spring:

>> CHECK OUT THE COURSE

1. Overview

Before Java 8, java.util.Date was one of the most commonly used classes for representing date-time values in Java.

Then Java 8 introduced java.time.LocalDateTime and java.time.ZonedDateTime. Java 8 also allows us to represent a specific time on the timeline using java.time.Instant.

In this tutorial, we’ll learn to add or subtract n hours from a given date-time in Java. We’ll first look at some standard Java date-time related classes, and then we’ll showcase a few third-party options.

To learn more about the Java 8 DateTime API, we would suggest reading this article.

2. java.util.Date

If we’re using Java 7 or lower, we can use the java.util.Date and java.util.Calendar classes for most date-time related handling.

Let’s see how to add n hours to a given Date object:

public Date addHoursToJavaUtilDate(Date date, int hours) {
    Calendar calendar = Calendar.getInstance();
    calendar.setTime(date);
    calendar.add(Calendar.HOUR_OF_DAY, hours);
    return calendar.getTime();
}

Note that Calendar.HOUR_OF_DAY is referring to a 24-hour clock.

The above method returns a new Date object, the value of which would be either (date + hours) or (date – hours), depending on whether we pass a positive or negative value of hours respectively.

Suppose we have a Java 8 application, but still we want to work our way with java.util.Date instances.

For such a case, we can opt to take the following alternate approach:

  1. Use java.util.Date toInstant() method to convert a Date object to a java.time.Instant instance
  2. Add a specific Duration to the java.time.Instant object using the plus() method
  3. Recover our java.util.Date instance by passing in the java.time.Instant object to the java.util.Date.from() method

Let’s have a quick look at this approach:

@Test
public void givenJavaUtilDate_whenUsingToInstant_thenAddHours() {
    Date actualDate = new GregorianCalendar(2018, Calendar.JUNE, 25, 5, 0)
      .getTime();
    Date expectedDate = new GregorianCalendar(2018, Calendar.JUNE, 25, 7, 0)
      .getTime();

    assertThat(Date.from(actualDate.toInstant().plus(Duration.ofHours(2))))
      .isEqualTo(expectedDate);
}

However, note that it’s always recommended to use the new DateTime API for all applications on Java 8 or higher versions.

3. java.time.LocalDateTime/ZonedDateTime

In Java 8 or later, adding hours to either a java.time.LocalDateTime or java.time.ZonedDateTime instance is pretty straightforward and makes use of the plusHours() method:

@Test
public void givenLocalDateTime_whenUsingPlusHours_thenAddHours() {
    LocalDateTime actualDateTime = LocalDateTime
      .of(2018, Month.JUNE, 25, 5, 0);
    LocalDateTime expectedDateTime = LocalDateTime.
      of(2018, Month.JUNE, 25, 10, 0);

    assertThat(actualDateTime.plusHours(5)).isEqualTo(expectedDateTime);
}

What if we wish to subtract a few hours?

Passing a negative value of hours to plusHours() method would do just fine. However, it’s recommended to use the minusHours() method:

@Test
public void givenLocalDateTime_whenUsingMinusHours_thenSubtractHours() {
    LocalDateTime actualDateTime = LocalDateTime
      .of(2018, Month.JUNE, 25, 5, 0);
    LocalDateTime expectedDateTime = LocalDateTime
      .of(2018, Month.JUNE, 25, 3, 0);
   
    assertThat(actualDateTime.minusHours(2)).isEqualTo(expectedDateTime);

}

The plusHours() and minusHours() methods in the java.time.ZonedDateTime works exactly the same way.

4. java.time.Instant

As we know, java.time.Instant introduced in Java 8 DateTime API represents a specific moment on the timeline.

To add some hours to an Instant object, we can use its plus() method with a java.time.temporal.TemporalAmount:

@Test
public void givenInstant_whenUsingAddHoursToInstant_thenAddHours() {
    Instant actualValue = Instant.parse("2018-06-25T05:12:35Z");
    Instant expectedValue = Instant.parse("2018-06-25T07:12:35Z");

    assertThat(actualValue.plus(2, ChronoUnit.HOURS))
      .isEqualTo(expectedValue);
}

Similarly, the minus() method can be used for subtracting a specific TemporalAmount.

5. Apache Commons DateUtils

The DateUtils class from the Apache Commons Lang library exposes a static addHours() method:

public static Date addHours(Date date, int amount)

The method takes-in a java.util.Date object along with an amount we wish to add to it, the value of which could be either positive or negative.

A new java.util.Date object is returned as an outcome:

@Test
public void givenJavaUtilDate_whenUsingApacheCommons_thenAddHours() {
    Date actualDate = new GregorianCalendar(2018, Calendar.JUNE, 25, 5, 0)
      .getTime();
    Date expectedDate = new GregorianCalendar(2018, Calendar.JUNE, 25, 7, 0)
      .getTime();

    assertThat(DateUtils.addHours(actualDate, 2)).isEqualTo(expectedDate);
}

The latest version of Apache Commons Lang is available at Maven Central.

6. Joda Time

Joda Time is an alternative to the Java 8 DateTime API and provides its own DateTime implementations.

Most of its DateTime related classes expose plusHours() and minusHours() methods to help us add or subtract a given number of hours from a DateTime object.

Let’s look at an example:

@Test
public void givenJodaDateTime_whenUsingPlusHoursToDateTime_thenAddHours() {
    DateTime actualDateTime = new DateTime(2018, 5, 25, 5, 0);
    DateTime expectedDateTime = new DateTime(2018, 5, 25, 7, 0);

    assertThat(actualDateTime.plusHours(2)).isEqualTo(expectedDateTime);
}

We can easily check the latest available version of Joda Time at Maven Central.

7. Conclusion

In this tutorial, we covered several ways to add or subtract a given number of hours from standard Java date-time values.

We also looked at some third-party libraries as an alternative. As usual, the complete source code is available over on Github.

I just announced the new Spring Boot 2 material, coming in REST With Spring:

>> CHECK OUT THE LESSONS