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

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

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

他のDate-Time APIのクラスに変換するメソッド(at、to、from)

 Date-Time APIのインスタンスから、その情報を引き継いで別のクラスのインスタンスを生成する方法は大きく分けて2パターンあります。一つは日付や時刻など足らない情報を追加することで別のクラスのインスタンスを生成する方法、もう一つは日付や時刻など不要な情報除くことで別のクラスのインスタンスを生成する方法です。

  1. 情報を追加するパターン
    • atメソッド
  2. 情報を除くパターン
    • toメソッド
    • fromメソッド
メソッド名/ prefix static /インスタンス 概要
at インスタンス 呼び出し元のインスタンスの情報に引数の情報の属性を追加して他のクラスのインスタンスを生成するメソッド
to インスタンス 呼び出し元のインスタンスの情報から属性を減らして他のクラスのインスタンスを生成するメソッド
from static 引数のインスタンスの情報から変換する対象のクラスに必要な属性を設定し新しいインスタンスを生成するメソッド。変換されるクラスが持たない属性は失われる。逆に変換されるクラスに必要な属性がないクラスを引数にしていると例外が発生する
LocalDateTime localDateTime = LocalDateTime.of(2014, 1, 2, 3, 4, 5);
System.out.println("localDateTime=" + localDateTime);
 
// atから始まるメソッドでOffset(UTCからの時差)の属性を追加
OffsetDateTime offsetDateTime = localDateTime.atOffset(ZoneOffset.of("+03:00"));
System.out.println("offsetDateTime=" + offsetDateTime);
 
// toから始まるメソッドでLocalDateの生成
LocalTime localTime = offsetDateTime.toLocalTime();
System.out.println("localTime=" + localTime);
 
// fromメソッドで引数のoffsetDateTimeからLocalTimeを生成
LocalDate localDate = LocalDate.from(offsetDateTime);
System.out.println("localDate=" + localDate);
サンプル
localDateTime=2014-01-02T03:04:05
offsetDateTime=2014-01-02T03:04:05+03:00
localTime=03:04:05
localDate=2014-01-02
実行結果

属性の値を変換するメソッド(plus、minus、with)

 インスタンスの属性の情報を変換した同じクラスのインスタンスを生成する方法には、属性の値に加算や減算を行う方法や、属性に直接値を設定する方法があります。

メソッド名 /prefix static /インスタンス 概要
plus インスタンス インスタンスの持つ情報に対象の属性を加算して、新しいインスタンスを生成するメソッド
minus インスタンス インスタンスの持つ情報に対象の属性を減算して、新しいインスタンスを生成するメソッド
with インスタンス インスタンスの持つ情報に対象の属性を引数で指定した値にし、新しいインスタンスを生成するメソッド

 これらのplus、minus、withメソッドの詳細については後述しますが、これらのメソッドは各属性に対し計算した値や新しい値が設定された新しいインスタンスを生成します。そして、Immutableなので、メソッドを実行したインスタンス自身の値は実行前と同じ値のままです。

比較を行うメソッド(equals、compareTo、is)

 Date-Time API には2つのDate-Time APIのインスタンスを比較するメソッドが用意されています。

メソッド名 /prefix static / インスタンス 概要
equals インスタンス 呼び出し元のインスタンスの引数のインスタンスの持つ情報が全く同じ場合、trueを返す。お互いのインスタンスが同じエポックからの経過時間を示していても、例えば、タイムゾーンが違うなど時差のため、年や月や日などの単位が違う場合はfalseとなる
compareTo インスタンス 呼び出し元のインスタンスの引数のインスタンスの持つ情報を比較して先の場合はマイナス値、同じ場合は0、後の場合はプラス値を返す。お互いのインスタンスが同じエポックからの経過時間を示していても、時差などで年や月や日などの単位が違う場合はそれらの単位で比較する
is インスタンス 比較する内容が正ならばtrueを返す

 isのprefixを持つメソッドの中には日時を比較するisEqualメソッド、isBeforeメソッド、isAfterメソッドがあります。これらのものは特に注意が必要で、equalsメソッドやcompareToメソッドがエポックからの経過時間および年や月や日などの単位でも比較するのに対し、isのprefixを持つメソッドは、それらが持つInstantのエポックからの経過時間の情報から比較しています。

 次のサンプルでは時差が違うために違う日時を表していますが、同じエポックからの経過時間を持っているもの同士の比較をしています。使うメソッドによる結果の違いに注目してください。

OffsetDateTime offsetDateTime1 = OffsetDateTime.of(2014, 9, 21, 10, 0, 0, 0, ZoneOffset.of("+00:00"));
Instant instant = Instant.from(offsetDateTime1);
OffsetDateTime offsetDateTime2 = OffsetDateTime.ofInstant(instant, ZoneOffset.of("+02:00"));
 
System.out.println("offsetDateTime1 = " + offsetDateTime1);
System.out.println("offsetDateTime2 = " + offsetDateTime2);
 
System.out.println("offsetDateTime1.equals(offsetDateTime2) → " + offsetDateTime1.equals(offsetDateTime2));
System.out
.println("offsetDateTime1.compareTo(offsetDateTime2) → " + offsetDateTime1.compareTo(offsetDateTime2));
System.out.println("offsetDateTime1.isEqual(offsetDateTime2) → " + offsetDateTime1.isEqual(offsetDateTime2));
System.out.println("offsetDateTime1.isAfter(offsetDateTime2) → " + offsetDateTime1.isAfter(offsetDateTime2));
System.out.println("offsetDateTime1.isBefore(offsetDateTime2) → " + offsetDateTime1.isBefore(offsetDateTime2));
サンプル1:同じエポックからの経過時間
offsetDateTime1 = 2014-09-21T10:00Z
offsetDateTime2 = 2014-09-21T12:00+02:00
offsetDateTime1.equals(offsetDateTime2) → false
offsetDateTime1.compareTo(offsetDateTime2) → -1
offsetDateTime1.isEqual(offsetDateTime2) → true
offsetDateTime1.isAfter(offsetDateTime2) → false
offsetDateTime1.isBefore(offsetDateTime2) → false
結果1

 次のサンプルは同じ日時で時差がある場合の比較の例です。

OffsetDateTime offsetDateTime1 = OffsetDateTime.of(2014, 9, 21, 11, 0, 0, 0, ZoneOffset.of("+00:00"));
OffsetDateTime offsetDateTime2 = OffsetDateTime.of(2014, 9, 21, 11, 0, 0, 0, ZoneOffset.of("+02:00"));
 
System.out.println("offsetDateTime1 = " + offsetDateTime1);
System.out.println("offsetDateTime2 = " + offsetDateTime2);
 
System.out.println("offsetDateTime1.equals(offsetDateTime2) → " + offsetDateTime1.equals(offsetDateTime2));
System.out
.println("offsetDateTime1.compareTo(offsetDateTime2) → " + offsetDateTime1.compareTo(offsetDateTime2));
System.out.println("offsetDateTime1.isEqual(offsetDateTime2) → " + offsetDateTime1.isEqual(offsetDateTime2));
System.out.println("offsetDateTime1.isAfter(offsetDateTime2) → " + offsetDateTime1.isAfter(offsetDateTime2));
System.out.println("offsetDateTime1.isBefore(offsetDateTime2) → " + offsetDateTime1.isBefore(offsetDateTime2));
サンプル2:同じ日時
offsetDateTime1 = 2014-09-21T11:00Z
offsetDateTime2 = 2014-09-21T11:00+02:00
offsetDateTime1.equals(offsetDateTime2) → false
offsetDateTime1.compareTo(offsetDateTime2) → 1
offsetDateTime1.isEqual(offsetDateTime2) → false
offsetDateTime1.isAfter(offsetDateTime2) → true
offsetDateTime1.isBefore(offsetDateTime2) → false
実行結果2

文字列の解析や書式を指定した文字列を生成するメソッド(parse、format、toString)

メソッド名 / prefix static /インスタンス 概要
parse static 引数の文字列を解析し新しいDate-Time APIのクラスのインスタンスを生成するメソッド
format インスタンス Date-Time APIのクラスのインスタンスの情報を書式で指定した文字列にするメソッド
toString インスタンス ISO 8601を基にしたクラスの場合、ISO 8601の拡張表記を基にした書式の文字列を生成する

 これらのメソッドについての詳細は後述しますが、文字列の解析や書式を指定した文字列を生成を行うのに、特定の書式となるDateTimeFormatterを指定する方法と、指定しない場合があります。独自の書式を設定するDateTimeFormatterを指定しない場合、デフォルトであるISO 8601の拡張表記を基にした書式が使われます。

 例えば、日付は年月日を「-」(ハイフン)で区切り、時刻は「:」(コロン)で区切り、日付と時刻の両方の場合は日付と時刻の間に「T」を入れて連結させたものになります。

 また、Objectから継承されたtoStringメソッドも決まった書式で日時を表示します。基本的にはISO 8601を基にしているクラスの場合、インスタンスの情報をISO 8601の拡張表記を基にした書式で出力します。そして、エポックからの経過時間を表すInstantの場合も、UTCでの日時に換算した情報をISO 8601の拡張表記を基にした書式で出力します。

// デフォルトでの解析
LocalDateTime localDateTime = LocalDateTime.parse("2014-10-01T23:59:59");
System.out.println("localDateTime=" + localDateTime);
 
// InstantのtoStringメソッド
ZonedDateTime zonedDateTime = ZonedDateTime.of(localDateTime, ZoneId.systemDefault());
Instant instant = Instant.from(zonedDateTime);
System.out.println("instant=" + instant.toString());
サンプル
localDateTime=2014-10-01T23:59:59
instant=2014-10-01T14:59:59Z
実行結果

開発者に実装をゆだねるqueryメソッド

メソッド名 / prefix static /インスタンス 概要
query インスタンス 引数のTemporalQueryを使って、呼び出し元のインスタンスを変換するメソッド

 このqueryメソッドは引数のTemporalQueryインターフェースを使ってqueryFromメソッドを使って結果を生成するメソッドです。このqueryFromメソッドは引数に呼び出し元自身のインスタンスを受け取り、それを使って結果のオブジェクトを返すメソッドです。結果は時間的オブジェクト以外にもLongなどでも可能です。

TemporalQuery<R>のqueryFromメソッドについて
戻り値 引数 概要
R queryFrom( TemporalAccessor temporal ) 引数の呼び出し元のインスタンスであるtemporalを受け取り、処理を行い結果としてRを返すメソッド

 このqueryメソッドの引数であるTemporalQueryは関数型インターフェースなので、ラムダ式やメソッド参照などを使って処理を実装可能です。

// 現在日時の取得
LocalDateTime localDateTime = LocalDateTime.now();
 
// 日付だけにする
LocalDate localDate = localDateTime.query(LocalDate::from);
 
// 結果の表示
System.out.println("localDateTime=" + localDateTime);
System.out.println("localDate=" + localDate);
サンプル
localDateTime=2014-12-24T00:39:00.377
localDate=2014-12-24
実行結果

Copyright © ITmedia, Inc. All Rights Reserved.

RSSについて

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

メールマガジン登録

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