Java 8日時APIの主なメソッドとフォーマット用のパターン文字の使い方:ここが大変だよJava 8 Date-Time API(2)(2/6 ページ)
Date-Timeの主なメソッド、ChronoUnit、DateTimeFormatterとフォーマット用のパターン文字などの使い方について解説します。
他のDate-Time APIのクラスに変換するメソッド(at、to、from)
Date-Time APIのインスタンスから、その情報を引き継いで別のクラスのインスタンスを生成する方法は大きく分けて2パターンあります。一つは日付や時刻など足らない情報を追加することで別のクラスのインスタンスを生成する方法、もう一つは日付や時刻など不要な情報除くことで別のクラスのインスタンスを生成する方法です。
- 情報を追加するパターン
- atメソッド
- 情報を除くパターン
- 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));
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
次のサンプルは同じ日時で時差がある場合の比較の例です。
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));
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
文字列の解析や書式を指定した文字列を生成するメソッド(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などでも可能です。
戻り値 | 引数 | 概要 |
---|---|---|
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.
関連記事
- 初心者のための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に。基本的に後方互換性は維持するが、一部影響がある場合もあるという。