連載
Java 8日時APIの主なメソッドとフォーマット用のパターン文字の使い方:ここが大変だよJava 8 Date-Time API(2)(4/6 ページ)
Date-Timeの主なメソッド、ChronoUnit、DateTimeFormatterとフォーマット用のパターン文字などの使い方について解説します。
引数に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の場合は前月の最後の曜日になる |
| 日 | 月 | 火 | 水 | 木 | 金 | 土 | |
|---|---|---|---|---|---|---|---|
| 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種類の結果が取得できます。
| 呼び出し元 | 戻り値 | 概要 |
|---|---|---|
| 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.
関連記事
初心者のためのJavaラムダ式入門とJDKのインストール、IDEの環境構築
本連載では、今までJavaの経験はあっても「ラムダ式は、まだ知らない」という人を対象にラムダ式について解説していきます。初回は、ラムダ式の概要と利点、必要性、JDK 8のセットアップ、NetBeans、IntelliJ IDEA、Eclipseの環境構築について。
ラムダ式、JAR脱獄、JavaScript/Node.jsに接近するJDK 8、そして9へ
Java 8&Java EE 7に対応した「Spring Framework 4.0」正式版リリース
米Pivotalは2013年12月12日、オープンソースのJavaアプリケーションフレームワーク「Spring Framework 4.0」の正式版をリリースした。
JDK 8、TLS 1.2がデフォルトに
Javaの通信暗号化もTSL 1.2に。基本的に後方互換性は維持するが、一部影響がある場合もあるという。