1. 概要

このチュートリアルでは、 TemporalAdjuster を簡単に見て、いくつかの実用的なシナリオで使用します。

Java 8では、日付と時刻を操作するための新しいライブラリが導入されました。java.timeおよびTemporalAdjusterはその一部です。 java.timeの詳細については、この紹介記事を確認してください。

簡単に言えば、 TemporalAdjuster は、Temporalオブジェクトを調整するための戦略です。 TemporalAdjuster の使用法に入る前に、Temporalインターフェース自体を見てみましょう。

2. 一時的

Temporal は、使用する実装に応じて、日付、時刻、または両方の組み合わせの表現を定義します。

Temporal インターフェースには、次のような多くの実装があります。

  • LocalDate –タイムゾーンのない日付を表します
  • LocalDateTime –タイムゾーンなしの日付と時刻を表します
  • HijrahDate –これはイスラム暦システムの日付を表します
  • MinguoDate –これはMinguoカレンダーシステムの日付を表します
  • ThaiBuddhistDate –タイの仏教暦システムの日付を表します

3. TemporalAdjuster

この新しいライブラリに含まれているインターフェイスの1つは、TemporalAdjusterです。

TemporalAdjuster は、TemporalAdjustersクラスに多くの事前定義された実装がある機能インターフェイスです。 インターフェイスにはadjustInto()という名前の単一の抽象メソッドがあり、 Temporal オブジェクトを渡すことで、その実装のいずれかで呼び出すことができます。

TemporalAdjuster を使用すると、複雑な日付操作を実行できます。 たとえばの場合、次の日曜日、当月の最終日、または翌年の初日を取得できます。 もちろん、古いjava.util.Calendarを使用してこれを行うことができます。

ただし、新しいAPIは、事前定義された実装を使用して、基盤となるロジックを抽象化します。 詳細については、Javadocにアクセスしてください。

4. 事前定義されたTemporalAdjusters

クラスTemporalAdjustersには、 Temporal [X216X]オブジェクトを返す多くの事前定義された静的メソッドがあり、 Temporal の実装に関係なく、さまざまな方法でTemporalオブジェクトを調整します。 ]そうかもしれません。

これらのメソッドの短いリストとそれらの簡単な定義を次に示します。

  • dayOfWeekInMonth() –通常の曜日のアジャスター。 たとえば、3月の第2火曜日の日付
  • firstDayOfMonth() –当月の初日の日付のアジャスター
  • firstDayOfNextMonth() –翌月の初日の日付の調整
  • firstDayOfNextYear() –翌年の初日の日付の調整
  • firstDayOfYear() –今年の初日の日付のアジャスター
  • lastDayOfMonth() –当月の最終日の日付の調整
  • nextOrSame() –特定の曜日の次の発生日、または今日が必要な曜日と一致する場合は同じ日のアジャスター

ご覧のとおり、メソッドの名前はほとんど自明です。 TemporalAdjusters の詳細については、Javadocにアクセスしてください。

簡単な例から始めましょう–例のように特定の日付を使用する代わりに、 LocalDate.now()を使用してシステム時計から現在の日付を取得できます。

ただし、このチュートリアルでは、予想される結果が変更されたときにテストが失敗しないように、固定の日付を使用します。 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());
}

今月の最終日を取得する方法は次のとおりです。

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

5. カスタムTemporalAdjuster実装の定義

TemporalAdjusterのカスタム実装を定義することもできます。 これを行うには2つの異なる方法があります。

5.1. ラムダ式の使用

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());
}

この例では、ラムダ式を使用して、日付(2017-07-08)を保持するlocalDateオブジェクトに14日を追加するようにtemporalAdjusterオブジェクトを設定します。

ラムダ式を使用して独自の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);
});

コードのテスト:

@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. TemporalAdjusterインターフェイスを実装する

TemporalAdjuster インターフェースを実装することにより、2017-07-08以降の稼働日を取得するカスタムTemporalAdjusterを作成する方法を見てみましょう。

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);
    }
}

それでは、テストを実行してみましょう。

@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. 結論

このチュートリアルでは、 TemporalAdjuster とは何か、事前定義された TemporalAdjusters、の使用方法、およびカスタムTemporalAdjuster実装を2つに実装する方法を示しました。違う方法。

このチュートリアルの完全な実装は、GitHubにあります。