LoginSignup
11
17

More than 3 years have passed since last update.

パッケージ java.time.temporal のおさらいメモ

Last updated at Posted at 2018-01-30

概要

パッケージ java.time.temporalは、Date and Time APIのパッケージjava.timeのサブパッケージで、時間的オブジェクト(temporal object)を操作する基本的なインターフェースや列挙型が定義されています。
この記事は、これらのインターフェースの使い方をおさらいしたときの記録になります。

環境

  • Windows 10 Professional
  • Oracle JDK 1.8.0_162
  • Oracle JDK 10.0.1

参考

インタフェース Temporal

時間的オブジェクト(日付、時間、オフセット、またはそれらのなんらかの組合せなど)への読取り/書込みアクセスを定義するフレームワークレベルのインタフェースです。

時間的オブジェクト(temporal object)の実装クラスには、LocalDate, LocalDateTime, LocalTime, Year, YearMonthなどがあります。

注意
このインタフェースはフレームワークレベルのインタフェースであり、アプリケーション・コードで広範囲にわたって使用しないようにしてください。かわりに、LocalDateなどの具象型のインスタンスを作成して使い回してください。これには様々な理由がありますが、その1つはこのインタフェースの実装がISO以外の暦体系になっている可能性があることです。この問題の詳細は、ChronoLocalDateを参照してください。

minus

default Temporal minus(TemporalAmount amount)
default Temporal minus(long amountToSubtract, TemporalUnit unit)

簡単な用例

時間的オブジェクトにTemporalAmountで表現する時間量で減算します。

Period period = Period.ofDays(10);
LocalDate.of(2018, 1, 30).minus(period);

時間的オブジェクトにTemporalUnitで表現する単位で減算します。

LocalDate.of(2018, 1, 30).minus(10, ChronoUnit.DAYS);

この用例でいえばよりシンプルにminusDaysを使うこともできます。

LocalDate.of(2018, 1, 30).minusDays(10);

plus

default Temporal plus(TemporalAmount amount)
Temporal plus(long amountToAdd, TemporalUnit unit)

簡単な用例

時間的オブジェクトにTemporalAmountで表現する時間量で加算します。

Period period = Period.ofDays(10);
LocalDate.of(2018, 1, 30).plus(period);

時間的オブジェクトにTemporalUnitで表現する単位で加算します。

LocalDate.of(2018, 1, 30).plus(10, ChronoUnit.DAYS);

この用例でいえばよりシンプルにplusDaysを使うこともできます。

LocalDate.of(2018, 1, 30).plusDays(10);

until

2つの時間的オブジェクトの間の時間量を指定した単位で計算します。

long until(Temporal endExclusive, TemporalUnit unit)

簡単な用例

LocalDate endExclusive = LocalDate.of(2019, 1, 1);

LocalDate.of(2018, 1, 1).until(endExclusive, ChronoUnit.DAYS);
// → 365

LocalDate.of(2018, 1, 1).until(endExclusive, ChronoUnit.MONTHS);
// → 12

LocalDate.of(2018, 1, 1).until(endExclusive, ChronoUnit.YEARS);
// → 1

with

default Temporal with(TemporalAdjuster adjuster)
Temporal with(TemporalField field, long newValue)

簡単な用例

時間的オブジェクトのTemporalFieldで指定したフィールドを変更します。

LocalDate.of(2018, 1, 1).with(ChronoField.MONTH_OF_YEAR, 3);

この用例でいえばよりシンプルにwithMonthを使うこともできます。

LocalDate.of(2018, 1, 1).withMonth(3);

インタフェース TemporalAccessor

時間的オブジェクト(日付、時間、オフセット、またはそれらのなんらかの組合せなど)への読取り専用アクセスを定義するフレームワークレベルのインタフェースです。

サブインターフェースにTemporalがあり、実装クラスには, LocalDate, LocalDateTime, LocalTime, Month, MonthDay, Year, YearMonthなどがあります。

注意
このインタフェースはフレームワークレベルのインタフェースであり、アプリケーション・コードで広範囲にわたって使用しないようにしてください。かわりに、LocalDateなどの具象型のインスタンスを作成して使い回してください。これには様々な理由がありますが、その1つはこのインタフェースの実装がISO以外の暦体系になっている可能性があることです。この問題の詳細は、ChronoLocalDateを参照してください。

get

時間的オブジェクトの指定されたフィールドの値を返します。

default int get(TemporalField field)

簡単な用例

LocalDateTime.now().get(ChronoField.DAY_OF_MONTH);

この用例でいえばよりシンプルなgetDayOfMonthがあります。

LocalDateTime.now().getDayOfMonth();

query

時間的オブジェクトに関数型インターフェースTemporalQueryの実装を使って問い合わせをします。

default <R> R query(TemporalQuery<R> query)

簡単な用例

月の最初の日曜日の週をその月の第1週として、月の第2月曜日と第3木曜日を問い合わせるクエリです。
たとえば、2018年2月の第1週は2月4日(日)から始まる週とします。(2月1日(月)は、2018年1月の第4週に含まれます。)

TemporalQuery<Boolean> isRegularHoliday = accessor -> {
    LocalDate target = LocalDate.from(accessor);
    LocalDate first = target.with(TemporalAdjusters.firstInMonth(DayOfWeek.SUNDAY));
    switch (DayOfWeek.of(target.get(ChronoField.DAY_OF_WEEK))) {
        case MONDAY:
            if (target.equals(first.plusDays(8))) {
                return true;
            }
            break;
        case THURSDAY:
            if (target.equals(first.plusDays(18))) {
                return true;
            }
            break;
        default:
            break;
    }
    return false;
};

LocalDate.of(2018, 2, 5).query(isRegularHoliday);
// → false
LocalDate.of(2018, 2, 8).query(isRegularHoliday);
// → false
LocalDate.of(2018, 2,12).query(isRegularHoliday);
// → true
LocalDate.of(2018, 2,15).query(isRegularHoliday);
// → false
LocalDate.of(2018, 2,19).query(isRegularHoliday);
// → false
LocalDate.of(2018, 2,22).query(isRegularHoliday);
// → true
LocalDate.of(2018, 2,26).query(isRegularHoliday);
// → false

range

時間的オブジェクトの指定したフィールドの有効な範囲を返します。(たとえば月の日数、年の日数など)

default ValueRange range(TemporalField field)

簡単な用例

2020年2月の月の範囲を求めます。

ValueRange range = LocalDate.of(2020, 2, 1).range(ChronoField.DAY_OF_MONTH);
range.toString();
// 1- 29

インターフェース TemporalField

月、時刻などの日付/時間のフィールドを表すインターフェースで、実装クラスにEnum ChronoFieldがあります。

adjustInto

指定した日付/時間フィールドに値を設定した新しい時間的オブジェクトを返します。

<R extends Temporal> R adjustInto(R temporal, long newValue)

簡単な用例

ChronoField.MONTH_OF_YEAR.adjustInto(LocalDate.now(), 12);

一般的な使い方として、可読性が高くなるwithを使うようにします。

LocalDate.now().with(ChronoField.MONTH_OF_YEAR, 12);

この用例でいえばよりシンプルなwithMonthがあります。

LocalDate.now().withMonth(12);

列挙型 ChronoField

フィールドの標準セットです。

定義されている主な定数(抜粋)

  • YEAR : 年
  • MONTH_OF_YEAR : 月
  • DAY_OF_MONTH : 月の日
  • HOUR_OF_DAY : 時
  • MINUTE_OF_HOUR : 分
  • SECOND_OF_MINUTE : 秒
  • MILLI_OF_SECOND : 1秒のうちのミリ秒
  • MICRO_OF_SECOND : 1秒のうちのマイクロ秒
  • NANO_OF_SECOND : 1秒のうちのナノ秒

インタフェース TemporalUnit

日間、時間などの日付/時間の単位を表すインターフェースで、実装クラスにEnum ChronoUnitがあります。

addTo

時間的オブジェクトに日時の単位で表す時間量を加算した新しい時間オブジェクトを返します。

<R extends Temporal> R addTo(R temporal, long amount)

簡単な用例

ChronoUnit.DAYS.addTo(LocalDate.now(), 1);

一般的な使い方として、可読性が高くなるplusを使うようにします。

LocalDate.now().plus(1, ChronoUnit.DAYS);

この用例でいえばよりシンプルなplusDaysがあります。

LocalDate.now().plusDays(1);

between

2つの時間的オブジェクトの間の時間量を日時の単位で表した結果を返します。

long between(Temporal temporal1Inclusive, Temporal temporal2Exclusive)

簡単な用例

ChronoUnit.DAYS.between(LocalDate.now(), LocalDate.now().plusDays(3));

一般的な使い方として、可読性が高くなるuntilを使うようにします。

LocalDate.now().until(LocalDate.now().plusDays(3), ChronoUnit.DAYS);
// → 3

Periodのインスタンスを返すメソッドもあります。

Period period = LocalDate.now().until(LocalDate.now().plusDays(3));
period.getDays()
// → 3

isSupportedBy

時間的オブジェクトが日時の単位をサポートしているか確認します。

default boolean isSupportedBy(Temporal temporal)

簡単な用例

ChronoUnit.HOURS.isSupportedBy(LocalDateTime.now());
// → true
ChronoUnit.HOURS.isSupportedBy(LocalDate.now());
// → false
ChronoUnit.HOURS.isSupportedBy(LocalTime.now());
// → true
ChronoUnit.HOURS.isSupportedBy(YearMonth.now());
// → false

列挙型 ChronoUnit

日付期間の単位の標準セットです。

定義されている主な単位(抜粋)

  • YEARS : 1年の概念を表す単位。
  • MONTHS : 1か月の概念を表す単位。
  • DAYS : 1日の概念を表す単位。
  • HOURS : 1時間の概念を表す単位。
  • MINUTES : 1分の概念を表す単位。
  • SECONDS : 1秒の概念を表す単位。
  • MILLIS : 1ミリ秒の概念を表す単位 (1000分の1秒)
  • MICROS : 1マイクロ秒の概念を表す単位 (100万分の1秒)
  • NANOS : 1ナノ秒の概念を表す単位 (10億分の1秒)

インタフェース TemporalAmount

時間量を表すインターフェースで、具象クラスにはPeriod(年、月および日を格納する日付ベースの実装)、Duration(秒およびナノ秒を格納する時間ベースの実装)があります。

注意
このインタフェースはフレームワークレベルのインタフェースであり、アプリケーション・コードで広範囲にわたって使用しないようにしてください。かわりに、PeriodやDurationなどの具象型のインスタンスを作成して使い回してください。

Periodで表す時間量の例

1日を表す時間量

Period.ofDays(1);

1週間を表す時間量

Period.ofWeeks(1);

1カ月と10日を表す時間量

Period.ofMonths(1).plusDays(10);

Durationで表す時間量の例

1時間を表す時間量

Duration.ofHours(1);

30分を表す時間量

Duration.ofMinutes(30);

48時間を表す時間量

Duration.ofDays(2);

between

Duration.betweenで2つの時間的オブジェクトの時間量を計算することができます。

Duration duration = Duration.between(
    LocalDateTime.of(2018, 1, 1, 0, 0, 0),
    LocalDateTime.of(2018, 1, 2, 1, 2, 3)
);

duration.toDays();
// → 1
duration.toHours();
// → 25
duration.toMinutes();
// → 1502
duration.getSeconds();
// → 90123
  • ちなみに、Durationクラスはjava.timeパッケージです。

TemporalAmountを引数に取るメソッド

インタフェースTemporalAccessorを実装したクラスであればplus/minusメソッドにTemporalAmountを利用できます。

addTo

LocalDateやLocalDateTimeなどの時間的オブジェクトにPeriodやDurationなどで表現する時間量を加算し新しい時間的オブジェクトを返します。

Temporal addTo(Temporal temporal)

簡単な用例

Period daysOfLimit = Period.ofDays(10);
Temporal temporal = daysOfLimit.addTo(LocalDate.of(2018, 1, 1));
LocalDate.from(temporal);

一般的な使い方として、可読性が高くなるplusを使うようにします。

Period daysOfLimit = Period.ofDays(10);
LocalDate.of(2018, 1, 1).plus(daysOfLimit);

この用例でいえばよりシンプルなplusDaysがあります。

LocalDate.of(2018, 1, 1).plusDays(10);

subtractFrom

LocalDateやLocalDateTimeなどの時間的オブジェクトにPeriodやDurationなどで表現する時間量を減算し新しい時間的オブジェクトを返します。

Temporal subtractFrom(Temporal temporal)

簡単な用例

Period daysOfLimit = Period.ofDays(10);
Temporal temporal = daysOfLimit.subtractFrom(LocalDate.of(2018, 2, 1));
LocalDate.from(temporal);

一般的な使い方として、可読性が高くなるminusを使うようにします。

Period daysOfLimit = Period.ofDays(10);
LocalDate.of(2018, 2, 1).minus(daysOfLimit);

この用例でいえばよりシンプルなminusDaysがあります。

LocalDate.of(2018, 2, 1).minusDays(10);

インタフェース TemporalAdjuster

時間的オブジェクトを調整する(たとえば特定の曜日、月の第2月曜日、月末などに設定)ためのインターフェースです。
なお、一般的な時間調整(月末日を求めるなど)は、クラス
TemporalAdjustersに実装されています。
関数型インターフェースなので、ラムダ式やメソッド参照として利用できます。

TemporalAdjusterを引数に取るメソッド

インターフェースTemporalを実装したクラスであればwithメソッドにTemporalAdjusterを利用できます。

adjustInto

時間的オブジェクトをアジャスタで調整した結果を新しい時間的オブジェクトとして返します。

Temporal adjustInto(Temporal temporal)

簡単な用例

次の月の第2月曜日の日付を求めます。

TemporalAdjuster adjuster = temporal -> {
    LocalDate target = LocalDate.from(temporal);

    // 当月の第2月曜日
    LocalDate secondMonday = target
        .with(TemporalAdjusters.firstDayOfMonth())
        .with(TemporalAdjusters.nextOrSame(DayOfWeek.MONDAY))
        .plusDays(7);

    if (target.isBefore(secondMonday) || target.isEqual(secondMonday)) {
        return secondMonday;
    }

    // 来月の第2月曜日
    return secondMonday
        .with(TemporalAdjusters.firstDayOfNextMonth())
        .with(TemporalAdjusters.nextOrSame(DayOfWeek.MONDAY))
        .plusDays(7);
};

Temporal temporal = adjuster.adjustInto(LocalDate.of(2018, 1, 1));
LocalDateTime.from(temporal);
// → 2018-01-08

一般的な使い方として、可読性が高くなるwithを使うようにします。

LocalDatee.of(2018, 1, 29).with(adjuster);
// → 2018-02-12

クラス TemporalAdjusters

一般的でよく使用される時間調整処理(たとえば月初または月末の日を求める、翌週の水曜日を求めるなど)がstaticメソッドとして実装されているクラスです。

このクラスには、staticメソッドとして使用できるアジャスタの標準セットが含まれています。これらの機能を次に示します。

  • 月の最初または最後の日を見つける
  • 翌月の最初の日を見つける
  • その年の最初または最後の日を見つける
  • 翌年の最初の日を見つける
  • 月内の最初または最後の曜日(「6月の最初の水曜日」など)を見つける
  • 次または前の曜日(「次の木曜日」など)を見つける

簡単な用例

今日日付以降の次の月曜日を求めます。
当日も含めたい場合はTemporalAdjusters.nextOrSameを使用します。

LocalDate.now().with(TemporalAdjusters.next(DayOfWeek.MONDAY));

月末の日付を求めます。

LocalDate.now().with(TemporalAdjusters.lastDayOfMonth());

年末をの日付を求めます。

LocalDate.now().with(TemporalAdjusters.lastDayOfYear());

インタフェース TemporalQuery<R>

時間的オブジェクトへの問い合わせのためのインターフェースです。
実装クラスにTemporalQueriesがあります。
関数型インターフェースなので、ラムダ式やメソッド参照として利用できます。

TemporalQuery<R>を引数に取るメソッド

インタフェースTemporalAccessorを実装したクラスであればqueryメソッドにラムダ式やメソッド参照を使用できます。

queryFrom

R queryFrom(TemporalAccessor temporal)

簡単な用例

次の月曜日までの日数を求めます。

TemporalQuery<Long> daysOfNextMonday = accessor -> {
    LocalDate inc = LocalDate.from(accessor);
    LocalDate exc = inc.with(TemporalAdjusters.nextOrSame(DayOfWeek.MONDAY));
    return ChronoUnit.DAYS.between(inc, exc);
};

LocalDate.of(2018, 1, 29).query(daysOfNextMonday);
// → 0

LocalDate.of(2018, 1, 30).query(daysOfNextMonday);
// → 6

ラムダ式

LocalDate.of(2018, 1, 29).query( accessor -> {
    LocalDate inc = LocalDate.from(accessor);
    LocalDate exc = inc.with(TemporalAdjusters.next(DayOfWeek.MONDAY));
    return ChronoUnit.DAYS.between(inc, exc);
});
// → 7

メソッド参照

LocalDateTime.now().query(YearMonth::from);
// → 2018-01

クラス TemporalQueries

関数型インタフェースTemporalQueryを実装したクラスです。

localDate

時間的オブジェクトからLocalDateを問い合わせます。

public static TemporalQuery<LocalDate> localDate()

簡単な用例

LocalDate date = LocalDateTime.now().query(TemporalQueries.localDate());

メソッド参照

LocalDate date = LocalDateTime.now().query(LocalDate::from);

この用例でいえばよりシンプルなtoLocalDateがあります。

LocalDate date = localDateTime.now().toLocalDate();

localTime

時間的オブジェクトからLocalTimeを問い合わせます。

public static TemporalQuery<LocalTime> localTime()

簡単な用例

LocalTime time = LocalDateTime.now().query(TemporalQueries.localTime());

メソッド参照

LocalTime time = LocalDateTime.now().query(LocalTime::from);

この用例でいえばよりシンプルなtoLocalTimeがあります。

LocalTime time = localDateTime.now().toLocalTime();

Java 9で追加されたAPI

パッケージ java.time.temporal

  • モジュール: java.base

追加はありません。

パッケージ java.time

  • モジュール: java.base

クラス Clock

tickMillis

public static Clock tickMillis​(ZoneId zone)

クラス Duration

dividedBy

public long dividedBy​(Duration divisor)

toSeconds

public long toSeconds​()

toDaysPart

public long toDaysPart​()

toHoursPart

public int toHoursPart​()

toMinutesPart

public int toMinutesPart​()

toSecondsPart

public int toSecondsPart​()

toMillisPart

public int toMillisPart​()

toNanosPart

public int toNanosPart​()

truncatedTo

public Duration truncatedTo​(TemporalUnit unit)

クラス LocalDate

ofInstant

public static LocalDate ofInstant​(Instant instant, ZoneId zone)

datesUntil

public Stream<LocalDate> datesUntil​(LocalDate endExclusive)

datesUntil

public Stream<LocalDate> datesUntil​(LocalDate endExclusive, Period step)

toEpochSecond

public long toEpochSecond​(LocalTime time, ZoneOffset offset)

クラス LocalTime

ofInstant

public static LocalTime ofInstant​(Instant instant, ZoneId zone)

toEpochSecond

public long toEpochSecond​(LocalDate date, ZoneOffset offset)

クラス OffsetTime

toEpochSecond

public long toEpochSecond​(LocalDate date)

Java 10で追加されたAPI

パッケージ java.time.temporal

  • モジュール: java.base

追加はありません。

パッケージ java.time

  • モジュール: java.base

追加はありません。

Java 14で追加されたAPI

パッケージ java.time.temporal

  • モジュール: java.base

追加はありません。

パッケージ java.time

  • モジュール: java.base

追加はありません。

その他のおさらいメモ

11
17
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
11
17