Javaで日付/時間を扱うには従来はDate/Calendar/DateFormat等のクラスを使っていたが(以下、旧API)、Java8からはjava.timeパッケージに新しくAPIが追加された(以下、新API)。
しかし新APIはパッケージ数が5、クラス数は69もあり最初はどれをどう使うのか戸惑ってしまう。
そこで最低限これだけ覚えておけば旧APIと同じ事ができるという程度の情報をまとめてみた。
新APIの特徴(旧APIではデータ保持はDateクラス、日付操作はCalendarクラスと分かれていた)
最低限知っておくべきクラス。
日時クラス java.time.LocalDateTimeLocalDateTime
d = LocalDateTime.now();
インスタンスの作成 - of
//年月日時分秒を指定
LocalDateTime d1 = LocalDateTime.of(2015, 12, 15, 23, 30, 59);
//年月日時分秒と1秒未満のナノ秒を指定
LocalDateTime d2 = LocalDateTime.of(2015, 12, 15, 23, 30, 59, 999999999);
フィールドの取得 - get
日時オブジェクトから特定のフィールド値を取得する。
Calendar.get()に相当。
LocalDateTime d = LocalDateTime.now();
System.out.println(d.getYear());
System.out.println(d.getMonth());
System.out.println(d.getDayOfMonth());
System.out.println(d.getHour());
System.out.println(d.getMinute());
System.out.println(d.getSecond());
System.out.println(d.getNano());
System.out.println(d.get(ChronoField.YEAR));
値を変更してインスタンスの作成 - plus/minus/with
日時オブジェクトの値を変更して新しい日時オブジェクトを作成する。
Calendar.set()やCalendar.add()に相当。
LocalDateTime d = LocalDateTime.of(2015, 12, 15, 23, 30, 59);
System.out.println(d.plusDays(20)); //2016-01-04T23:30:59
System.out.println(d.minusDays(20)); //2015-11-25T23:30:59
System.out.println(d.withDayOfMonth(20)); //2015-12-20T23:30:59
時間を切り捨てる - truncatedTo
LocalDateTime.of(2015, 12, 15, 23, 30, 59).truncatedTo(ChronoUnit.HOURS);
// 2015-12-15T23:00
来月1日の12時
LocalDateTime d =
LocalDateTime.now()
.plusMonths(1)
.withDayOfMonth(1)
.withHour(12)
.truncatedTo(ChronoUnit.HOURS);
ZoneId/ZoneOffsetのインスタンス作成
ZoneId zoneId = ZoneId.systemDefault();
ZoneId zoneId = ZoneId.of("Asia/Tokyo");
ZoneOffset offset = ZoneOffset.UTC;
ZoneOffset offset = ZoneOffset.ofHours(9);
ZoneOffset offset = ZoneId.systemDefault().getRules().getOffset(Instant.now());
他の日時クラスに変換 - to/at
LocalDateTime ldt = LocalDateTime.now();
//LocalDateTime -> ZoneDateTime
ZonedDateTime zdt = ldt.atZone(ZoneId.systemDefault());
//LocalDateTime -> OffsetDateTime
OffsetDateTime odt = ldt.atOffset(ZoneOffset.ofHours(9));
//LocalDateTime -> Instant
Instant instant = ldt.toInstant(ZoneOffset.UTC);
ISO日時フォーマッタを使ったインスタンスの生成
日時クラスには予めISO日時フォーマッタを使った文字列から日時を作成するコンストラクタが用意されている。
LocalDateTime.parse("2015-12-15T23:30");
LocalDateTime.parse("2015-12-15T23:30:59");
LocalDateTime.parse("2015-12-15T23:30:59.999");
フォーマッタ
DateTimeFormatter f = DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss");
LocalDateTime d = LocalDateTime.parse("2015/12/15 23:30:59", f);
System.out.println(d.format(f));
*DateTimeクラスのparse()を使う時は時刻も含めないといけない。
Dateとの相互変換
日時オブジェクトとDate間の変換はInstantクラスを経由して行う。
//Date -> *DateTime
Date date = new Date();
ZonedDateTime zdt = date.toInstant().atZone(ZoneId.systemDefault());
LocalDateTime ldt = LocalDateTime.ofInstant(date.toInstant(), ZoneId.systemDefault());
OffsetDateTime odt = OffsetDateTime.ofInstant(date.toInstant(), ZoneId.systemDefault());
//ZonedDateTime -> Date
ZonedDateTime zdt = ZonedDateTime.now();
Date date = Date.from(zdt.toInstant());
//OffsetDateTime -> Date
OffsetDateTime odt = OffsetDateTime.now();
Date date = Date.from(odt.toInstant());
//LocalDateTime -> Date
LocalDateTime ldt = LocalDateTime.now();
Date date = Date.from(ldt.atZone(ZoneId.systemDefault()).toInstant());
日時クラスの一覧
最後に、使えそうな日時クラスの一覧。
日時クラスはTemporal又はTemporalAccessorの実装クラス、時間量を表すクラスはTemporalAmountの実装クラスとなっている。
代表的な日時クラス