在Java中将小时添加到日期

Add Hours To a Date In Java

1.概述

在Java 8之前,java.util.Date是表示Java中日期时间值的最常用的类之一。

然后Java 8引入了java.time.LocalDateTime和java.time.ZonedDateTime。 Java 8还允许我们使用java.time.Instant在时间轴上表示特定时间。

在本教程中,我们将学习在Java中从给定的日期时间增加或减少n小时。我们将首先看一些与Java日期时间相关的标准类,然后我们将展示一些第三方选项。

要了解有关Java 8 DateTime API的更多信息,建议阅读本文。

2. java.util.Date

如果使用的是Java 7或更低版??本,则可以使用java.util.Date和java.util.Calendar类进行大多数与日期时间相关的处理。

让我们看看如何将n小时添加到给定的Date对象:

1
2
3
4
5
6
public Date addHoursToJavaUtilDate(Date date, int hours) {
    Calendar calendar = Calendar.getInstance();
    calendar.setTime(date);
    calendar.add(Calendar.HOUR_OF_DAY, hours);
    return calendar.getTime();
}

请注意,Calendar.HOUR_OF_DAY是指24小时制。

上面的方法返回一个新的Date对象,其值将为(date + hours)或(date-hours),具体取决于我们分别传递的是小时的正值还是负值。

假设我们有一个Java 8应用程序,但仍然希望使用java.util.Date实例。

对于这种情况,我们可以选择采用以下替代方法:

  • 使用java.util.Date toInstant()方法将Date对象转换为java.time.Instant实例

  • 使用theplus()方法向java.time.Instant对象添加特定的Duration

  • 通过将java.time.Instant对象传递给java.util.Date.from()方法来恢复我们的java.util.Date实例。

  • 让我们快速看一下这种方法:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    @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);
    }

    但是,请注意,始终建议对Java 8或更高版本上的所有应用程序使用新的DateTime API。

    3. java.time.LocalDateTime / ZonedDateTime

    在Java 8或更高版本中,将小时数添加到java.time.LocalDateTime或java.time.ZonedDateTime实例非常简单,并使用了plusHours()方法:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    @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);
    }

    如果我们想减去几个小时怎么办?

    将小时数的负值传递给plusHours()方法就可以了。但是,建议使用minusHours()方法:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    @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);

    }

    java.time.ZonedDateTime中的plusHours()和minusHours()方法的工作方式完全相同。

    4. java.time.Instant

    众所周知,Java 8 DateTime API中引入的java.time.Instant表示时间轴上的特定时刻。

    要为Instant对象增加一些时间,我们可以将其plus()方法与ajava.time.temporal.TemporalAmount结合使用:

    1
    2
    3
    4
    5
    6
    7
    8
    @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);
    }

    类似地,minus()方法可用于减去特定的TemporalAmount。

    5. Apache Commons DateUtils

    Apache Commons Lang库中的TheDateUtils类公开了一个静态的addHours()方法:

    1
    public static Date addHours(Date date, int amount)

    该方法接收一个java.util.Date对象以及一个我们希望添加的对象,该对象的值可以是正数或负数。

    作为结果返回一个新的java.util.Date对象:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    @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);
    }

    Maven Central提供了最新版本的Apache Commons Lang。

    6.乔达时间

    Joda Time是Java 8 DateTime API的替代方法,并提供了自己的DateTimeimplementation。

    它的大多数与DateTime相关的类都公开plusHours()和minusHours()方法,以帮助我们从DateTime对象中添加或减去给定的小时数。

    让我们看一个例子:

    1
    2
    3
    4
    5
    6
    7
    @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);
    }

    我们可以在Maven Central轻松查看Joda Time的最新可用版本。

    7.结论

    在本教程中,我们介绍了几种从标准Ja??va日期时间值中增加或减少给定小时数的方法。

    我们还研究了一些第三方库作为替代方案。与往常一样,完整的源代码可在GitHub上获得。