JavaSE8 Goldへの道(Upgrade to Java SE 8 Programmer 1Z0-810 試験対策)12回目です。
一連の記事は「JavaSE8Gold」ラベルを付けていきます。
いよいよ最終回です。最後は日時に基づく各種計算方法を解説します。
一連の記事は「JavaSE8Gold」ラベルを付けていきます。
いよいよ最終回です。最後は日時に基づく各種計算方法を解説します。
Clockクラス
java.time.Clock
クラスは、Instant
と同じようにある時点を示しますが、基本的な使い方は外的要因で定まる日時をシステムに与えるケースで、日時クラスの生成時に渡してやることでシステム全体の日時を制御するために使えます。例えば
LocalDateTime#now
の引数に渡します。Clock
の生成方法は以下のようなものがあります。//システムデフォルトのタイムゾーンで生成 Clock.systemDefaultZone(); //UTCで生成 Clock.systemUTC(); //タイムゾーンを指定して生成 Clock.system(ZoneId.of("Asia/Tokyo")); //固定日時で生成→このクロックで生成する日時は常に固定になる Clock.fixed(Instant.parse("2018-04-24T16:35:44Z"), ZoneId.of("Asia/Tokyo")); //秒以下が常に0で、1分ごとに進む Clock.tickMinutes(ZoneId.systemDefault()); //ナノ秒フィールドが常に0(ミリ秒以下)で、1秒毎に進む Clock.tickSeconds(ZoneId.systemDefault()); //指定された単位のDurationで進む Clock.tick(Clock.systemDefaultZone(), Duration.of(2, ChronoUnit.SECONDS));
fixed
メソッドで生成されたClock
を引数にしたLocalDateTime#now
(他の日時クラスも同様)の結果は、常に固定の値になります。また
tick~
メソッドでは特定の単位でのみ進むようになります。よくあるパターンでは「業務日付」などと呼ばれる、DB等で管理されるカレンダーに従って動くシステムを実装する際や、テストにおいて特定の日(月初や年初など)を指定できるように、
Clock
を元に日時クラスを生成しておくと良さそうです。Durationクラス
Instant now = Instant.now(); //「1時間」を表す時間量 Duration d = Duration.ofHours(1); Instant then = now.plus(d); System.out.println("now : " + now + " ; then : " + then);
実行結果
now : 2018-04-24T07:43:33.515Z ; then : 2018-04-24T08:43:33.515Z
Duration
同士を足し合わせたり、自身の値に対して加減算したコピーを生成することができます。Duration d1 = Duration.ofHours(1); Duration d2 = Duration.ofDays(2); d1 = d1.plus(d2); System.out.println("Total duration : " + d1);
実行結果
Total duration : PT49H
Duration#toString
の結果は、ISO-8601秒ベース表現を使用した文字列表現です(PT8H6M12.345Sなど)。「PT」のあと、時分秒が記号で表されます。それより大きな単位(日など)は次に出てくる
Period
クラスと混同しないように時間単位で出力されるようです。Periodクラス
こちらも紹介済みの、日付ベースの時間量を表すクラスです。
参考サイトのサンプルコード
参考サイトのサンプルコード
LocalDate today = LocalDate.parse("2018-04-24"); Period sixDays = Period.ofDays(7); LocalDate nextWeek = today.plus(sixDays); System.out.println("next week : " + nextWeek);
実行結果
next week : 2018-05-01
そのままですね。
between
メソッドも解説済みですが。LocalDate newYear = LocalDate.parse("2018-01-01"); Period passed = Period.between(newYear, LocalDate.now()); System.out.println("passed since NY : " + passed);
実行結果
passed since NY : P3M23D
Period#toString
もISO-8601の期間フォーマットで出力されます。先頭にPがついて、記号と共に表されます。TemporalUnit
java.time.temporal.TemporalUnit
インタフェースは日時の単位を表すものです。その実装として
ChronoUnit
列挙型があります。ちょうど、
Calendar
クラスである単位の値を取るときに定数を指定したのと同じようなイメージです。※もう一つ、
TemporalField
というインタフェースもあり、実装としてChronoField
列挙型があります。ChronoUnit
は時間量のDuration
,Period
や日時の加減算に使用し、ChronoField
は日時クラスの各要素にアクセスする際(get
やwith
メソッドなど)に指定します。参考サイトのサンプルコード
LocalDate today = LocalDate.now(); System.out.println("Today: " + today); LocalDate twoWeeksLater = today.plus(2, ChronoUnit.WEEKS); System.out.println("Two weeks later: " + twoWeeksLater);
実行結果
Today: 2018-04-24 Two weeks later: 2018-05-08
ChronoUnit
の定義を見ると、一般的なDAYS
、HOURS
などの他に、CENTURIES
やFOREVER
なんてのもあります。FOREVER
の説明は「永遠の概念を表す人為的単位。」とあり、なんか哲学的です。各日時クラスには
truncatedTo
メソッドというのがあり、引数で指定したTemporalUnit
よりも小さい単位を切り詰めた日時を返します。LocalDateTime ldtStart = LocalDateTime.of(2018, 4, 23, 12, 7, 1); LocalDateTime ldtEnd = LocalDateTime.of(2018, 4, 23, 15, 8, 2); LocalDateTime ldtStartNew = ldtStart.truncatedTo(ChronoUnit.MINUTES); System.out.println("Start time truncated to minutes : " + ldtStartNew); LocalDateTime ldtEndNew = ldtEnd.truncatedTo(ChronoUnit.HOURS); System.out.println("End time truncated to hours : " + ldtEndNew);
実行結果
Start time truncated to minutes : 2018-04-23T12:07 End time truncated to hours : 2018-04-23T15:00
ChronoUnit#between
メソッドを使うと、自身の単位で2つの日時の差を計算できます。LocalDateTime ldtStart = LocalDateTime.of(2018, 4, 23, 12, 7, 1); LocalDateTime ldtEnd = LocalDateTime.of(2018, 4, 23, 15, 8, 2); long numberOfHours = ChronoUnit.HOURS.between(ldtStart, ldtEnd); System.out.println("Between in hours : " + numberOfHours); long numberOfMinutes = ChronoUnit.MINUTES.between(ldtStart, ldtEnd); System.out.println("Between in minutes : " + numberOfMinutes);
実行結果
Between in hours : 3 Between in minutes : 181
と、い、う、わ、け、で
これでJava SE 8 Goldアップグレード試験の全範囲の解説が終わりました。 もうチケットは買ったので、近い内に受験して結果を報告したいと思います。 一連の記事が、皆様のお役に立てば幸いです。
今回も以下のサイトとGoldの通常試験の参考書を参考にしています。