日時クラスとは?
2017/3/31 勉強会
トラッシュブリーフィング合同会社
satoshi
1
1 Javaにおける日時クラスとは
2 仕組み
3 エポックタイム
4 デメリット
5 Date型に変わる日時クラス
6 まとめ
2
目次
・特定の時刻時点を表すクラス
3
1.Javaにおける日時クラスとは
Dateクラスが持つ情報は時刻情報ではなく
「今どの時点にあるか?」という情報を持つ機能
■時刻を取得方法
4
2-1.仕組み(日時の取得)
協定世界時(UTC)の1970年1月1日午前0時(エポックタイム)から
何ミリ秒経過しているかで時刻を判断している
例
未来日:2017年3月18日16時4分24秒 → 1489820664ミリ秒
過去日:1960年3月18日16時4分24秒 → -308940936ミリ秒
■協定世界時(UTC)だけではイギリスの時刻しか使えない?
5
2-2.仕組み(タイムゾーン)
時差(タイムゾーン)にあわせて時刻を取得することが出来る
・TimeZoneクラス
取得したタイムゾーン情報をCalendarクラス等に設定することで
設定したタイムゾーンの時刻を取得する事が出来るクラス
モスクワの
タイムゾーンを設
定
日本時刻
出力時刻
6
3-1.エポックタイムその1
■エポックタイムとは
・「 1970年1月1日午前0時から
現在の日時がどの時点であるのか?」
を判断するために基準にとなる日時
・エポックタイムはサーバーの時間設定に
基づいて設定されている。
7
3-2.エポックタイムその2
■DBやアプリケーションが動作しているサーバーによって
設定されている日時が同じだとは限らない
DB
正しい日時
APサーバー
内部日時が9時間ずれている
例えば:Aの処理によってJava(APサーバー)で
日時を設定しDBにデータを登録した
2017年3月28日 17時00分00秒
Bの処理はDBで取得した日時を元に
Aで保存したデータを検索した。
2017年3月29日 2時00分00秒
検索結果
実際は同じ時刻なのに
検索されなかった
8
3-3.エポックタイムその3
■サーバーごとの日時が違ってしまうことは解消できるのか?
業務アプリ内の時間を同じサーバーで取得してしまえばいい
DB(UTC)
正しい日時
APサーバー(UTC)
内部日時が9時間ずれている
日時情報要求
日時情報応答
日時情報取得
アプリ内の日時情報の流れ
9
3-4.エポックタイムその4
■日時を統一する方法
処理を共通化することが一般的
手法例:
OracleDB等の「シノニム」機能を利用しDBサーバーの時刻を取得する
業務アプリ内で日時の取得元を同じにすれば全体で
同じ日時情報を使用することが出来る
■Calendarクラスへの依存度が大きい
10
5-1.デメリットその1
・Dateクラス単体では日付の計算を行うことが出来ない
・タイムゾーンの指定はDateクラスではできない
・Dateクラスの機能の多くがCalendarクラスへ置き換えられており、
「@Deprecated(推奨されないメソッド)」となっている
■ Calendarクラス月が実際の月-1で表示される
11
5-2.デメリットその2
Calendarクラス
Dateクラス
・このままでは画面に表示できない
画面表示できる形式に変換する必要があ
る
・日付、時刻どちらかが必要なくてもすべ
ての
情報を格納してしまう
コードが長くな
り
めんどくさい
■Java8より登場したクラス「JSR-310」
12
6-1.Date型に変わる日時クラス
・LocalDate 時間の情報を除いた'2010-12-03'のような日を表現する
(日付日付のみ)
・LocalTime 日の情報を除いた、'11:30' のような時間を表現する
(時間のみ保持する)
・LocalDateTime '2010-12-03T11:30'のような日時を表現する
(日時両方を保持する)
・ZonedDateTime タイムゾーンを含めた日時を表現する
(タイムゾーン管理を行うことが出来る)
・OffsetDateTime オフセット(時差)を含めた日時を表現する
(任意で時差の設定を行うことが出来る)
13
6-2. Date型に変わる日時クラスその2
■Dateとの違いは?
・エポックタイムからの時点を取得するという思想はそのままだが、
精度がミリ秒からナノ秒へ変更されている
・Date型はエポックタイムからの時点の情報のみを扱うもの
だったが、日時情報そのものを扱うことが出来るようになった
・ Calendarクラスに実装されている機能も単体の機能として
使用できるようになった
14
6-3. Date型に変わる日時クラスその3
■LocalDateクラス(日付)
時刻情報が不要な場合使用できる機能
日付を“YYYY-MM-DD”表記で出力することが出来る
nowメソッド(現在の日付を取得する事が出来るメソッド)
15
6-4.Date型に変わる日時クラスその4
■LocalTimeクラス(時刻)
日付情報が不要な場合使用できる機能
時刻を“hh:mm:ss”表記で出力することが出来る
nowメソッド(現在の時刻を取得する事が出来るメソッド)
16
6-5. Date型に変わる日時クラスその5
■LocalDateTimeクラス(時刻)
日時情報が不要な場合使用できる機能
日時を“YYYY-MM-DDThh:mm:ss”表記で出力することが出来る
nowメソッド(現在の日時を取得する事が出来るメソッド)
17
6-6. Date型に変わる日時クラスその6
■ZonedDateTimeクラス(タイムゾーンを含む日時)
指定したタイムゾーンの時刻を取得し
YYYY-MM-DDThh:mm:ss[timezone]形式で出力することが出来る
nowメソッド(現在の日時を取得する事が出来るメソッド)
18
6-7. Date型に変わる日時クラスその7
■ZonedDateTimeクラスを使用することのメリット
今まで
データベースに時間管理を任せていたため時刻を取得しようと
するたびにシノニムを呼び出す共通処理が必要だった
ZonedDateTimeクラスを使うと
ZonedDateTimeに設定するタイムゾーンさえ統一すればDB処理
を呼び出す必要がなくなった。
19
6-8. Date型に変わる日時クラスその8
■OffsetDateTimeクラス
時差の設定を行
う
オフセット(時差)を含めた日時を取得し
YYYY-MM-DDThh:mm:ss+mm:ss表記で出力することが出来る
設定したUTCか
らの時差を表示
する
20
補足:Clockクラス
Java8で追加された現在時刻の設定を行うクラス
JSR-310の各クラスにはnowメソッドの機能として
Clockクラスの日時取得機能は「すでに実装されている」
// 現在時刻を設定する
localDatetime.now(Clock.systemUTC);
Clockクラスの注目ポイントとして、
「実施コストが下がる」が挙げられている
fixedメソッド:引数として指定した任意の日時情報を設定する
// 設定された時刻:2015-12-15T23:30:59.999999999
Clock.fixed( ZonedDateTime.of(2015, 12, 15, 23, 30, 59,
999999999, ZoneId.systemDefault()).toInstant(),
ZoneId.systemDefault());
21
補足:Clockクラス(DIを利用したテスト実施)
Aクラス
Bクラスの呼び出しを
要求する
DI : Dependency Injection(依存性の注入)の略
クラスをインスタンス化せず、「DIコンテナ」を経由して処理を呼び出す機能
(詳細は割愛)
DIコンテナ Bクラス(now)
Bクラス(fixed)
設定によって違う
Bクラスを呼び出す
「DIコンテナ」の設定を切り替えることでfixedメソッドを用いたクラスを呼び出
し任意の日時情報でテストを行う事が出来る。
22
6-9. Date型に変わる日時クラスその9
■Date型ではCalendarクラスを用いて計算を行っていた
JSR-310では他のクラスを呼び出すことなく
加算減算を行うことが出来るようになった。
plus(加算)メソッド、minus(減算)メソッド
引数として渡した値分日付、時間を加算減算することが出来る
4日と3時間後の時刻
が出力される
23
6-10. Date型に変わる日時クラスその10
■Date型ではCalendarクラスを用いて比較を行っていた。
JSR-310では他のクラスを呼び出すことなく
比較を行うことが出来るようになった。
二つの時刻を
比較する
24
6. まとめ
1
3
Date型はエポックタイムからの時点のみを保存することが出来る。
時刻は協定世界時(UTC)で取得することを基本としてるが、タイムゾーンを
設定することで時差を苦にすることなく扱うことが出来る
Date型弱点を補った新たなクラス「JSR-310」
・型そのもので日時情報を扱えるようになった
・タイムゾーンの指定にCalenderクラスを用いる必要がなくなった。
・計算や比較が楽になった
2
終わり
25

日時クラスとは?