連載
» 2015年01月29日 18時00分 公開

Java 8日時APIの主なメソッドとフォーマット用のパターン文字の使い方ここが大変だよJava 8 Date-Time API(2)(4/6 ページ)

[長谷川智之,株式会社ビーブレイクシステムズ]

引数にTemporalAdjusterインターフェースを受け取るwithメソッド

 また、withメソッドには引数にTemporalAdjusterインターフェースを受け取るものも用意されています。このTemporalAdjusterインターフェースは呼び出し元のインスタンスから、例えば月末など、特定の日や時間を設定した新たなインスタンスを生成するために使うインターフェースです。

 例えば、月の月末の日を取得するメソッドが実装されたTemporalAdjusterをwithメソッドの引数に渡すことにより、呼び出し元のインスタンスの日の値が月末の日になったインスタンスを生成します。

ZonedDateTime zonedDateTime = ZonedDateTime.now();
System.out.println(zonedDateTime);
System.out.println(zonedDateTime.with(TemporalAdjusters.lastDayOfMonth()));
サンプル
2014-11-25T22:25:07.170+09:00[Asia/Tokyo]
2014-11-30T22:25:07.170+09:00[Asia/Tokyo]
実行結果

TemporalAdjusterを返すメソッド

 またDate-Time APIでは、本稿でも使われているTemporalAdjusterを返すstaticなメソッドを持つTemporalAdjustersクラスがあります。このクラスが返すTemporalAdjusterのメソッドの主なものは下記になります。

メソッド 概要
firstDayOfMonth() 日の値を月初にした時間的オブジェクトを生成するTemporalAdjusterを返すメソッド
lastDayOfMonth() 日の値を月末の日にした時間的オブジェクトを生成するTemporalAdjusterを返すメソッド
firstDayOfNextMonth() 月と日の値を翌月の月初にした時間的オブジェクトを生成するTemporalAdjusterを返すメソッド
firstDayOfNextYear() 年と月と日の値を翌年の初日にした時間的オブジェクトを生成するTemporalAdjusterを返すメソッド
lastDayOfNextYear() 年と月と日の値を翌年の末日にした時間的オブジェクトを生成するTemporalAdjusterを返すメソッド
firstInMonth(DayOfWeek dayOfWeek) 指定したdayOfWeekの曜日が呼び出し元の月の最初に現れる日にした時間的オブジェクトを生成するTemporalAdjusterを返すメソッド
lastInMonth(DayOfWeek dayOfWeek) 指定したdayOfWeekの曜日が呼び出し元の月の最後に現れる日にした時間的オブジェクトを生成するTemporalAdjusterを返すメソッド
next(DayOfWeek dayOfWeek) 指定したdayOfWeekの曜日が次に現れる日にした時間的オブジェクトを生成するTemporalAdjusterを返すメソッド
previous(DayOfWeek dayOfWeek) 指定したdayOfWeekの曜日が一つ前に現れた日にした時間的オブジェクトを生成するTemporalAdjusterを返すメソッド
nextOrSame(DayOfWeek dayOfWeek) 指定したdayOfWeekの曜日が同じ日の場合は同じ日時を持つ時間的オブジェクト、違う場合は次に現れる日を持つ時間的オブジェクトを生成するTemporalAdjusterを返すメソッド
previousOrSame(DayOfWeek dayOfWeek) 指定したdayOfWeekの曜日が同じ日の場合は同じ日時を持つ時間的オブジェクト、違う場合は一つ前に現れた日を持つ時間的オブジェクトを生成するTemporalAdjusterを返すメソッド
dayOfWeekInMonth(int value, DayOfWeek dayOfWeek) 指定したdayOfWeekの曜日がvalueで指定した日を持つ時間的オブジェクトを生成するTemporalAdjusterを返すメソッド。valueが正の数の場合はその月の月初から数えた週の日、負の数の場合は月末から逆に数えた週の日、0の場合は前月の最後の曜日になる


2014年8月の場合
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
31
LocalDate localDate = LocalDate.of(2014, 8, 15);
 
LocalDate result = localDate.with(TemporalAdjusters.firstDayOfMonth());
System.out.println("firstDayOfMonth(): " + result);
 
result = localDate.with(TemporalAdjusters.lastDayOfMonth());
System.out.println("lastDayOfMonth(): " + result);
 
result = localDate.with(TemporalAdjusters.firstDayOfNextMonth());
System.out.println("firstDayOfNextMonth(): " + result);
 
result = localDate.with(TemporalAdjusters.firstDayOfYear());
System.out.println("firstDayOfYear(): " + result);
 
result = localDate.with(TemporalAdjusters.lastDayOfYear());
System.out.println("lastDayOfYear(): " + result);
 
result = localDate.with(TemporalAdjusters.firstInMonth(DayOfWeek.FRIDAY));
System.out.println("firstInMonth(DayOfWeek.FRIDAY): " + result);
 
result = localDate.with(TemporalAdjusters.lastInMonth(DayOfWeek.FRIDAY));
System.out.println("lastInMonth(DayOfWeek.FRIDAY): " + result);
 
result = localDate.with(TemporalAdjusters.next(DayOfWeek.FRIDAY));
System.out.println("next(DayOfWeek.FRIDAY): " + result);
 
result = localDate.with(TemporalAdjusters.previous(DayOfWeek.FRIDAY));
System.out.println("previous(DayOfWeek.FRIDAY): " + result);
 
result = localDate.with(TemporalAdjusters.nextOrSame(DayOfWeek.FRIDAY));
System.out.println("nextOrSame(DayOfWeek.FRIDAY): " + result);
 
result = localDate.with(TemporalAdjusters.nextOrSame(DayOfWeek.WEDNESDAY));
System.out.println("nextOrSame(DayOfWeek.WEDNESDAY): " + result);
 
result = localDate.with(TemporalAdjusters.previousOrSame(DayOfWeek.FRIDAY));
System.out.println("previousOrSame(DayOfWeek.FRIDAY): " + result);
 
result = localDate.with(TemporalAdjusters.previousOrSame(DayOfWeek.WEDNESDAY));
System.out.println("previousOrSame(DayOfWeek.WEDNESDAY): " + result);
サンプル1
firstDayOfMonth(): 2014-08-01
lastDayOfMonth(): 2014-08-31
firstDayOfNextMonth(): 2014-09-01
firstDayOfYear(): 2014-01-01
lastDayOfYear(): 2014-12-31
firstInMonth(DayOfWeek.FRIDAY): 2014-08-01
lastInMonth(DayOfWeek.FRIDAY): 2014-08-29
next(DayOfWeek.FRIDAY): 2014-08-22
previous(DayOfWeek.FRIDAY): 2014-08-08
nextOrSame(DayOfWeek.FRIDAY): 2014-08-15
nextOrSame(DayOfWeek.WEDNESDAY): 2014-08-20
previousOrSame(DayOfWeek.FRIDAY): 2014-08-15
previousOrSame(DayOfWeek.WEDNESDAY): 2014-08-13
実行結果1
LocalDate localDate = LocalDate.of(2014, 8, 15);
System.out.println(localDate.with(TemporalAdjusters.dayOfWeekInMonth(1, DayOfWeek.SUNDAY)));
System.out.println(localDate.with(TemporalAdjusters.dayOfWeekInMonth(10, DayOfWeek.SUNDAY)));
System.out.println(localDate.with(TemporalAdjusters.dayOfWeekInMonth(-1, DayOfWeek.SUNDAY)));
System.out.println(localDate.with(TemporalAdjusters.dayOfWeekInMonth(-10, DayOfWeek.SUNDAY)));
System.out.println(localDate.with(TemporalAdjusters.dayOfWeekInMonth(0, DayOfWeek.SUNDAY)));
サンプル2
2014-08-03
2014-10-05
2014-08-31
2014-06-29
2014-07-27
実行結果2

期間の計算を行うbetweenメソッド

 Date-Time APIでは期間を計算するメソッドとしてbetweenメソッドが用意されています。このbetweenメソッドは引数に2つのDate-Time APIのインスタンスを受け取り、これら2つの間で発生する期間を算出します。このbetweenメソッドは実行するクラスによって大きく分けて次の3種類の結果が取得できます。

3種類のbetweenメソッド
呼び出し元 戻り値 概要
Duration Duration 引数の2つの時間的オブジェクトから、秒とナノ秒で期間を算出するメソッド
Period Period 引数の2つの時間的オブジェクトから、年と月と日で期間を算出するメソッド
ChronoUnit long 引数の2つの時間的オブジェクトから、ChronoUnitが表す単位での期間をlongで算出するメソッド
LocalDateTime localDateTime1 = LocalDateTime.now();
Thread.sleep(1234);
LocalDateTime localDateTime2 = LocalDateTime.now();
 
System.out.println("localDateTime1=" + localDateTime1);
System.out.println("localDateTime2=" + localDateTime2);
 
Duration duration = Duration.between(localDateTime1, localDateTime2);
System.out.println("duration=" + duration);
System.out.println("duration.getSeconds()=" + duration.getSeconds());
System.out.println("duration.getNano()=" + duration.getNano());
サンプル(Duration)
localDateTime1=2014-11-25T22:47:03.623
localDateTime2=2014-11-25T22:47:04.870
duration=PT1.247S
duration.getSeconds()=1
duration.getNano()=247000000
実行結果
LocalDate localDate1 = LocalDate.now();
LocalDate localDate2 = localDate1.with(TemporalAdjusters.lastDayOfYear()).plusYears(1);
 
System.out.println("localDate1=" + localDate1);
System.out.println("localDate2=" + localDate2);
 
Period period = Period.between(localDate1, localDate2);
System.out.println("period=" + period);
System.out.println("period.getYears()=" + period.getYears());
System.out.println("period.getMonths()=" + period.getMonths());
System.out.println("period.getDays()=" + period.getDays());
サンプル(Period)
localDate1=2014-11-25
localDate2=2015-12-31
period=P1Y1M6D
period.getYears()=1
period.getMonths()=1
period.getDays()=6
実行結果
LocalDate localDate1 = LocalDate.now();
LocalDate localDate2 = localDate1.with(TemporalAdjusters.lastDayOfYear()).plusYears(1);
 
System.out.println("localDate1=" + localDate1);
System.out.println("localDate2=" + localDate2);
 
long years = ChronoUnit.YEARS.between(localDate1, localDate2);
long months = ChronoUnit.MONTHS.between(localDate1, localDate2);
long days = ChronoUnit.DAYS.between(localDate1, localDate2);
 
System.out.println("years=" + years);
System.out.println("months=" + months);
System.out.println("days=" + days);
サンプル(ChronoUnit)
localDate1=2014-11-25
localDate2=2015-12-31
years=1
months=13
days=401
実行結果

 また、betweenメソッドでは比較した時間的オブジェクトが違う時差を持つ場合、時差を考慮した計算ではなく、その時点での計算となります。

// UTCからの時差のみ変更
OffsetDateTime offsetDateTime1 = OffsetDateTime.of(2014, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC);
OffsetDateTime offsetDateTime2 = OffsetDateTime.of(2014, 1, 1, 0, 0, 0, 0, ZoneOffset.of("+0900"));
 
Duration duration = Duration.between(offsetDateTime1, offsetDateTime2);
System.out.println("duration=" + duration);
 
long hours = ChronoUnit.HOURS.between(offsetDateTime1, offsetDateTime2);
System.out.println("hours=" + hours);
サンプル
PT-9H
hours=-9
実行結果

Copyright © ITmedia, Inc. All Rights Reserved.

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。