TemporalAdjuster in Java – Java中的TemporalAdjuster

最后修改: 2017年 7月 10日

中文/混合/英文(键盘快捷键:t)

1. Overview

1.概述

In this tutorial, we’ll have a quick look at the TemporalAdjuster and use it in a few practical scenarios.

在本教程中,我们将快速了解TemporalAdjuster并在一些实际场景中使用它。

Java 8 introduced a new library for working with dates and times – java.time and TemporalAdjuster is a part of it. If you want to read more about the java.time, check this introductory article.

Java 8引入了一个用于处理日期和时间的新库–java.timeTemporalAdjuster是它的一部分。如果你想阅读更多关于java.time的信息,请查看这篇介绍性文章。

Simply put, TemporalAdjuster is a strategy for adjusting a Temporal object. Before getting into the usage of TemporalAdjuster, let’s have a look at the Temporal interface itself.

简单地说,TemporalAdjuster是一种调整Temporal对象的策略。在了解TemporalAdjuster的用法之前,让我们看看Temporal接口本身。

2. Temporal

2.时间性

A Temporal defines a representation of a date, time, or a combination of both, depending on the implementation we’re going to be using.

一个Temporal定义了一个日期、时间或两者的组合的表示,这取决于我们要使用的实现。

There are a number of implementations of the Temporal interface, including:

有许多Temporal接口的实现,包括。

  • LocalDate – which represents a date without a timezone
  • LocalDateTime – which represents a date and time without a timezone
  • HijrahDate – which represents a date in the Hijrah calendar system
  • MinguoDate – which represents a date in the Minguo calendar system
  • ThaiBuddhistDate – which represents a date in the Thai Buddhist calendar system

3. TemporalAdjuster

3.TemporalAdjuster

One of the interfaces included in this new library is TemporalAdjuster.

这个新库中包含的接口之一是TemporalAdjuster

TemporalAdjuster is a functional interface which has many predefined implementations in the TemporalAdjusters class. The interface has a single abstract method named adjustInto() which can be called in any of its implementations by passing a Temporal object to it.

TemporalAdjuster是一个功能接口,在TemporalAdjusters类中有许多预定义的实现。该接口有一个名为adjustInto()的抽象方法,通过向其传递一个Temporal对象,可以在其任何实现中调用。

TemporalAdjuster allows us to perform complex date manipulations. For example, we can obtain the date of the next Sunday, the last day of the current month or the first day of the next year. We can, of course, do this using the old java.util.Calendar.

TemporalAdjuster允许我们进行复杂的日期操作。例如,我们可以获得下一个星期天的日期、当前月份的最后一天或下一年的第一天。当然,我们可以使用旧的java.util.Calendar来完成这个任务。

However, the new API abstracts away the underlying logic using its predefined implementations. For more information, visit the Javadoc.

然而,新的API使用其预定义的实现对底层逻辑进行了抽象。欲了解更多信息,请访问Javadoc>。

4. Predefined TemporalAdjusters

4.预定义的TemporalAdjusters

The class TemporalAdjusters has many predefined static methods that return a TemporalAdjuster object to adjust Temporal objects in many different ways no matter what implementation of Temporal they might be.

TemporalAdjusters有许多预定义的静态方法,它们返回一个TemporalAdjuster对象,以许多不同的方式调整Temporal对象,不管它们是什么实现的Temporal

Here’s a short list of these methods and a quick definition of them:

下面是这些方法的简短清单和对它们的快速定义。

  • dayOfWeekInMonth() – an adjuster for the ordinal day-of-week. For example the date of the second Tuesday in March
  • firstDayOfMonth() – an adjuster for the date of the first day of the current month
  • firstDayOfNextMonth() – an adjuster for the date of the first day of the next month
  • firstDayOfNextYear() – an adjuster for the date of the first day of the next year
  • firstDayOfYear() – an adjuster for the date of the first day of the current year
  • lastDayOfMonth() – an adjuster for the date of the last day of the current month
  • nextOrSame() – an adjuster for the date of the next occurrence of a specific day-of-week or the same day in case today matches the required day-of-week

As we can see, the methods’ names are pretty much self-explanatory. For more TemporalAdjusters, visit the Javadoc.

正如我们所看到的,这些方法的名称几乎是不言自明的。关于更多的TemporalAdjusters,请访问Javadoc>。

Let’s start with a simple example – instead of using a specific date as in the examples, we can use LocalDate.now() to get the current date from the system clock.

让我们从一个简单的例子开始–我们可以使用LocalDate.now()来获取系统时钟的当前日期,而不是像例子中那样使用一个特定的日期。

But, for this tutorial, we’re going to use a fixed date so that the tests won’t fail later when the expected result changes. Let’s see how we can use the TemporalAdjusters class to obtain the date of the Sunday after 2017-07-08:

但是,在本教程中,我们要使用一个固定的日期,这样在以后预期结果改变时,测试就不会失败。让我们看看如何使用TemporalAdjusters类来获得2017-07-08之后的周日的日期。

@Test
public void whenAdjust_thenNextSunday() {
    LocalDate localDate = LocalDate.of(2017, 07, 8);
    LocalDate nextSunday = localDate.with(TemporalAdjusters.next(DayOfWeek.SUNDAY));
    
    String expected = "2017-07-09";
    
    assertEquals(expected, nextSunday.toString());
}

Here’s how we can obtain the last day of the current month:

下面是我们如何获得当前月的最后一天。

LocalDate lastDayOfMonth = localDate.with(TemporalAdjusters.lastDayOfMonth());

5. Defining Custom TemporalAdjuster Implementations

5.定义自定义的TemporalAdjuster实现

We can also define our custom implementations for TemporalAdjuster. There are two different ways of doing this.

我们也可以为TemporalAdjuster定义我们的自定义实现。有两种不同的方式来做这件事。

5.1. Using Lambda Expressions

5.1.使用Lambda表达式

Let’s see how we can obtain the date that’s 14 days after 2017-07-08 using the Temporal.with() method:

让我们看看如何使用Temporal.with()方法获得2017-07-08之后14天的日期。

@Test
public void whenAdjust_thenFourteenDaysAfterDate() {
    LocalDate localDate = LocalDate.of(2017, 07, 8);
    TemporalAdjuster temporalAdjuster = t -> t.plus(Period.ofDays(14));
    LocalDate result = localDate.with(temporalAdjuster);
    
    String fourteenDaysAfterDate = "2017-07-22";
    
    assertEquals(fourteenDaysAfterDate, result.toString());
}

In this example, using a lambda expression, we set the temporalAdjuster object to add 14 days to the localDate object, which holds the date (2017-07-08).

在这个例子中,使用lambda表达式,我们设置temporalAdjuster对象为localDate对象增加14天,该对象持有日期(2017-07-08)。

Let’s see how we can obtain the date of the working day right after 2017-07-08 by defining our own TemporalAdjuster implementations using a lambda expression. But, this time, by using the ofDateAdjuster() static factory method:

让我们看看如何通过使用lambda表达式定义我们自己的TemporalAdjuster实现来获得2017-07-08之后的工作日的日期。但是,这次是通过使用ofDateAdjuster()静态工厂方法。

static TemporalAdjuster NEXT_WORKING_DAY = TemporalAdjusters.ofDateAdjuster(date -> {
    DayOfWeek dayOfWeek = date.getDayOfWeek();
    int daysToAdd;
    if (dayOfWeek == DayOfWeek.FRIDAY)
        daysToAdd = 3;
    else if (dayOfWeek == DayOfWeek.SATURDAY)
        daysToAdd = 2;
    else
        daysToAdd = 1;
    return today.plusDays(daysToAdd);
});

Testing our code:

测试我们的代码。

@Test
public void whenAdjust_thenNextWorkingDay() {
    LocalDate localDate = LocalDate.of(2017, 07, 8);
    TemporalAdjuster temporalAdjuster = NEXT_WORKING_DAY;
    LocalDate result = localDate.with(temporalAdjuster);

    assertEquals("2017-07-10", date.toString());
}

5.2. By Implementing the TemporalAdjuster Interface

5.2.通过实现TemporalAdjuster接口

Let’s see how we can write a custom TemporalAdjuster that obtains the working day after 2017-07-08 by implementing the TemporalAdjuster interface:

让我们看看如何通过实现TemporalAdjuster接口,编写一个自定义的TemporalAdjuster,获得2017-07-08之后的工作日。

public class CustomTemporalAdjuster implements TemporalAdjuster {

    @Override
    public Temporal adjustInto(Temporal temporal) {
        DayOfWeek dayOfWeek 
          = DayOfWeek.of(temporal.get(ChronoField.DAY_OF_WEEK));
        
        int daysToAdd;
        if (dayOfWeek == DayOfWeek.FRIDAY)
            daysToAdd = 3;
        else if (dayOfWeek == DayOfWeek.SATURDAY)
            daysToAdd = 2;
        else
            daysToAdd = 1;
        return temporal.plus(daysToAdd, ChronoUnit.DAYS);
    }
}

Now, let’s run our test:

现在,让我们运行我们的测试。

@Test
public void whenAdjustAndImplementInterface_thenNextWorkingDay() {
    LocalDate localDate = LocalDate.of(2017, 07, 8);
    CustomTemporalAdjuster temporalAdjuster = new CustomTemporalAdjuster();
    LocalDate nextWorkingDay = localDate.with(temporalAdjuster);
    
    assertEquals("2017-07-10", nextWorkingDay.toString());
}

6. Conclusion

6.结论

In this tutorial, we’ve shown what TemporalAdjuster is, predefined TemporalAdjusters, how they can be used, and how we can implement our custom TemporalAdjuster implementations in two different ways.

在本教程中,我们展示了什么是TemporalAdjuster、预定义的TemporalAdjuster,如何使用,以及我们如何以两种不同的方式实现我们的自定义TemporalAdjuster实现。

The full implementation of this tutorial can be found over on GitHub.

本教程的完整实现可以在GitHub上找到over