🐈

【JavaGold対策】〜Date and Time API(日付/時刻API)編〜

2023/09/22に公開

Date and Time API(日付/時刻API)

日付、時間、時間間隔などを表すAPI

<メリット>
  • 日付、時刻、日時などを表すクラスを提供
  • Date and Time APIの各クラスは不変オブジェクト(イミュータブル)のため、
    スレッドセーフである
  • 日時演算に関する機能を提供


LocalDateクラス

日付を表すクラス

<LocalDateインスタンス取得メソッド>
メソッド名 説明
static LocalDate now() 現在日付からLocalDateインスタンスを取得
static LocalDate of(
  int year,
  int month,
  int dayOfMonth)
指定した年、月、日からLocalDateインスタンスを取得
static LocalDate parse(CharSequence text) テキスト文字列からLocalDateインスタンスを取得
<LocalDateの加減算メソッド>
メソッド名 説明
LocalDate plus(long amountToAdd, TemporalUnit unit) 指定された量を加算した、このLocalDateのコピーを返す
LocalDate plus(TemporalAmount amountToAdd) 指定された量を加算した、このLocalDateのコピーを返す
LocalDate plusDays(long daysToAdd) 指定された日数を加算した、このLocalDateのコピーを返す
LocalDate plusMonths(long monthsToAdd) 指定された月数を加算した、このLocalDateのコピーを返す
LocalDate plusWeeks(long weeksToAdd) 指定された週数を加算した、このLocalDateのコピーを返す
LocalDate plusYears(long yearsToAdd) 指定された年数を加算した、このLocalDateのコピーを返す
LocalDate minus(long amountToSubtract, TemporalUnit unit) 指定された量を減算した、この日付のコピーを返す
LocalDate minus(TemporalAmount amountToSubtract) 指定された年数を減算した、このLocalDateのコピーを返す
LocalDate minusDays(long daysToSubtract) 指定された日数を減算した、このLocalDateのコピーを返す
LocalDate minusMonths(long monthsToSubtract) 指定された月数を減算した、このLocalDateのコピーを返す
LocalDate minusWeeks(long weeksToSubtract) 指定された週数を減算した、このLocalDateのコピーを返す
LocalDate minusYears(long yearsToSubtract) 指定された年数を減算した、このLocalDateのコピーを返す


Sample.java
package com.sample;

import java.time.LocalDate;

public class Sample {
    public static void main(String[] args) {
        LocalDate date1 = LocalDate.now();
        LocalDate date2 = LocalDate.of(2023, 07, 27);
        LocalDate date3 = LocalDate.parse("2023-07-27");

        System.out.println("現在の日付    : " + date1);
        System.out.println("1日後の日付   : " + date1.plusDays(1));
        System.out.println("3週間後の日付 : " + date1.plusWeeks(3));
        System.out.println("6ヶ月後の日付 : " + date1.plusMonths(6));
        System.out.println("3年後の日付   : " + date1.plusYears(3));
    }
}
実行結果
現在の日付    : 2023-09-21
1日後の日付   : 2023-09-22
3週間後の日付 : 2023-10-12
6ヶ月後の日付 : 2024-03-21
3年後の日付   : 2026-09-21


LocalTimeクラス

時刻を表すクラス

<LocalTimeインスタンス取得メソッド>
メソッド名 説明
static LocalTime now() 現在時刻からLocalTimeインスタンスを取得
static LocalTime of(
  int hour,
  int minute,
  int second)
指定した時、分、秒からLocalTimeインスタンスを取得
static LocalTime parse(CharSequence text) テキスト文字列からLocalTimeインスタンスを取得
<LocalTimeの加減算メソッド>
メソッド名 説明
LocalTime plus(long amountToAdd, TemporalUnit unit) 指定された量を加算した、このLocalTimeのコピーを返す
LocalTime plus(TemporalAmount amountToAdd) 指定された時間を加算した、このLocalTimeのコピーを返す
LocalTime plusHours(long hoursToAdd) 指定された時間数を加算した、このLocalTimeのコピーを返す
LocalTime plusMinutes(long minutesToAdd) 指定された分数を加算した、このLocalTimeのコピーを返す
LocalTime plusSeconds(long secondsToAdd) 指定された秒数を加算した、このLocalTimeのコピーを返す
LocalTime plusNanos(long nanosToAdd) 指定されたナノ秒数を加算した、このLocalTimeのコピーを返す
LocalTime minus(long amountToSubtract, TemporalUnit unit) 指定された量を減算した、この時刻のコピーを返す
LocalTime minus(TemporalAmount amountToSubtract) 指定された時間を減算した、このLocalTimeのコピーを返す
LocalTime minusHours(long hoursToSubtract) 指定された時間数を減算した、このLocalTimeのコピーを返す
LocalTime minusMinutes(long minutesToSubtract) 指定された分数を減算した、このLocalTimeのコピーを返す
LocalTime minusSeconds(long secondsToSubtract) 指定された秒数を減算した、このLocalTimeのコピーを返す
LocalTime minusNanos(long nanosToSubtract) 指定されたナノ秒数を減算した、このLocalTimeのコピーを返す


Sample.java
package com.sample;

import java.time.LocalTime;

public class Sample {
    public static void main(String[] args) {
        LocalTime time1 = LocalTime.now();
        LocalTime time2 = LocalTime.of(2, 03, 40, 5);
        LocalTime time3 = LocalTime.parse("12:04:56.789");

        System.out.println("現在時刻          : " + time1);
        System.out.println("1時間後の時刻     : " + time1.plusHours(1));
        System.out.println("3分後の時刻       : " + time1.plusMinutes(3));
        System.out.println("6秒後の時刻       : " + time1.plusSeconds(6));
        System.out.println("3ナノ秒後の時刻   : " + time1.plusNanos(3));
    }   
}
実行結果
現在時刻          : 15:37:52.007
1時間後の時刻     : 16:37:52.007
3分後の時刻       : 15:40:52.007
6秒後の時刻       : 15:37:58.007
3ナノ秒後の時刻   : 15:37:52.007000003


LocalDateTimeクラス

日時を表すクラス

<LocalDateTimeインスタンス取得メソッド>
メソッド名 説明
static LocalDateTime now() 現在日時からLocalDateTimeインスタンスを取得
static LocalDateTime of(
  int year,
  int month,
  int dayOfMonth,
  int hour,
  int minute,
  int second)
指定した時、分、秒からLocalTimeインスタンスを取得
static LocalDateTime of(
  int year,
  Month month,
  int dayOfMonth,
  int hour,
  int minute,
  int second)
指定した時、分、秒からLocalTimeインスタンスを取得
static LocalDateTime of(
  LocalDate date,
  LocalTime time)
LocalDateとLocalTimeからLocalTimeインスタンスを取得
static LocalDateTime parse(CharSequence text) テキスト文字列からLocalDateTimeインスタンスを取得
<LocalDateTimeの加減算メソッド>
メソッド名 説明
LocalDateTime plus(long amountToAdd, TemporalUnit unit) 指定された量を加算した、このLocalDateTimeのコピーを返す
LocalDateTime plus(TemporalAmount amountToAdd) 指定された時間を加算した、このLocalDateTimeのコピーを返す
LocalDateTime plusDays(long days) 指定された日数を加算した、このLocalDateTimeのコピーを返す
LocalDateTime plusMonths(long months) 指定された月数を加算した、このLocalDateTimeのコピーを返す
LocalDateTime plusWeeks(long weeks) 指定された週数を加算した、このLocalDateTimeのコピーを返す
LocalDateTime plusYears(long years) 指定された年数を加算した、このLocalDateTimeのコピーを返す
LocalDateTime plusHours(long hours) 指定された時間数を加算した、このLocalDateTimeのコピーを返す
LocalDateTime plusMinutes(long minutes) 指定された分数を加算した、このLocalDateTimeのコピーを返す
LocalDateTime plusSeconds(long seconds) 指定された秒数を加算した、このLocalDateTimeのコピーを返す
LocalDateTime plusNanos(long nanos) 指定されたナノ秒数を加算した、このLocalDateTimeのコピーを返す
LocalDateTime minus(long amountToSubtract, TemporalUnit unit) 指定された量を減算した、このLocalDateTimeのコピーを返す
LocalDateTime minus(TemporalAmount amountToSubtract) 指定された時間を減算した、このLocalDateTimeのコピーを返す
LocalDateTime minusDays(long days) 指定された日数を減算した、このLocalDateTimeのコピーを返す
LocalDateTime minusMonths(long months) 指定された月数を減算した、このLocalDateTimeのコピーを返す
LocalDateTime minusWeeks(long weeks) 指定された週数を減算した、このLocalDateTimeのコピーを返す
LocalDateTime minusYears(long years) 指定された年数を減算した、このLocalDateTimeのコピーを返す
LocalDateTime minusHours(long hours) 指定された時間数を減算した、このLocalDateTimeのコピーを返す
LocalDateTime minusMinutes(long minutes) 指定された分数を減算した、このLocalDateTimeのコピーを返す
LocalDateTime minusSeconds(long seconds) 指定された秒数を減算した、このLocalDateTimeのコピーを返す
LocalDateTime minusNanos(long nanos) 指定されたナノ秒数を減算した、このLocalDateTimeのコピーを返す


Sample.java
package com.sample;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.Month;

public class Sample {
    public static void main(String[] args) {
        LocalDateTime dateTime1 = LocalDateTime.now();
        LocalDateTime dateTime2 = LocalDateTime.of(2023, 9, 23, 23, 59, 59);
        LocalDateTime dateTime3 = LocalDateTime.of(2023, Month.SEPTEMBER, 5, 2, 59, 59);
        LocalDateTime dateTime4 = LocalDateTime.parse("2023-09-23T23:59:59");

        LocalDate date = LocalDate.now();
        LocalTime time = LocalTime.now();
        LocalDateTime dateTime5 = LocalDateTime.of(date, time);

        System.out.println("現在の日時      : " + dateTime1);
        System.out.println("2年後の日時     : " + dateTime1.plusYears(2));
        System.out.println("3ヶ月後の日時   : " + dateTime1.plusMonths(3));
        System.out.println("4週間後の日時   : " + dateTime1.plusWeeks(4));
        System.out.println("5日後の日時     : " + dateTime1.plusDays(5));
        System.out.println("6時間後の日時   : " + dateTime1.plusHours(6));
        System.out.println("7分後の日時     : " + dateTime1.plusMinutes(7));
        System.out.println("8秒後の日時     : " + dateTime1.plusSeconds(8));
        System.out.println("9ナノ秒後の日時 : " + dateTime1.plusNanos(9));
    }
}
実行結果
現在の日時      : 2023-09-22T16:21:51.718
2年後の日時     : 2025-09-22T16:21:51.718
3ヶ月後の日時   : 2023-12-22T16:21:51.718
4週間後の日時   : 2023-10-20T16:21:51.718
5日後の日時     : 2023-09-27T16:21:51.718
6時間後の日時   : 2023-09-22T22:21:51.718
7分後の日時     : 2023-09-22T16:28:51.718
8秒後の日時     : 2023-09-22T16:21:59.718
9ナノ秒後の日時 : 2023-09-22T16:21:51.718000009


Periodクラス

年月日単位の間隔を表すクラス


Sample.java
package com.sample;

import java.time.LocalDate;
import java.time.Month;
import java.time.Period;

public class Sample {
    public static void main(String[] args) {
        LocalDate fromDate = LocalDate.of(2023, Month.JULY, 17);   // 開始日
        LocalDate toDate = LocalDate.of(2025, Month.FEBRUARY, 25); // 終了日
        Period period = Period.between(fromDate, toDate);          // 開始日と終了日の間の期間を表すPeriodオブジェクトを生成

        System.out.println("Period     : " + period);
        System.out.println("年単位の間隔 : " + period.getYears());
        System.out.println("月単位の間隔 : " + period.getMonths());
        System.out.println("日単位の間隔 : " + period.getDays());
    }
}
実行結果
Period     : P1Y7M8D
年単位の間隔 : 1
月単位の間隔 : 7
日単位の間隔 : 8
<Periodクラスのメソッド>
メソッド名 説明
static Period of(
int years,
int months,
int days)
指定された年数、月数、日数を含むPeriodインスタンスを取得
static Period ofYears(int years) 指定された年数を含むPeriodを取得(月数と日数はゼロになる)
static Period of ofMonths(int months) 指定された月数を含むPeriodを取得(年数と日数はゼロになる)
static Period of ofWeeks(int weeks) 指定された週数に7を掛けた値を日数にした値を含むPeriodを取得(年数と月数はゼロになる)
static Period ofDays(int days) 指定された日数を含むPeriodを取得(年数と月数はゼロになる)


Durationクラス

時間単位の間隔を表すクラス


Sample.java
package com.sample;

import java.time.Duration;
import java.time.LocalTime;

public class Sample {
    public static void main(String[] args) {
        LocalTime startTime = LocalTime.of(12, 34, 56, 789);
        LocalTime endTime = LocalTime.of(23, 45, 6, 149);
        Duration duration = Duration.between(startTime, endTime);
        System.out.println("Duration      : " + duration);
        System.out.println("日単位の間隔    : " + duration.toDays());
        System.out.println("時単位の間隔    : " + duration.toHours());
        System.out.println("分単位の間隔    : " + duration.toMinutes());
        System.out.println("秒単位の間隔    : " + duration.getSeconds());
        System.out.println("ミリ秒単位の間隔 : " + duration.toMillis());
        System.out.println("ナノ秒単位の間隔 : " + duration.toNanos());
    }
}
実行結果
Duration      : PT11H10M9.99999936S
日単位の間隔    : 0
時単位の間隔    : 11
分単位の間隔    : 670
秒単位の間隔    : 40209
ミリ秒単位の間隔 : 40209999
ナノ秒単位の間隔 : 40209999999360


Instantクラス

- 時系列上の単一時点を表す

- エポック秒を保持する

<Instantインスタンス取得メソッド>
メソッド名 説明
static Instant now() 現在のInstantインスタンスを取得
static Instant ofEpochSecond(long epochSecond) 1970-01-01T00:00:00Zからの指定した秒数を使用したInstantインスタンスを取得
static Instant ofEpochSecond(
  long epochSecond,
  long nanoAdjustment)
1970-01-01T00:00:00Zからの指定した秒数とナノ秒数を使用したInstantインスタンスを取得
static Instant ofEpochMilli(long epochMilli) 1970-01-01T00:00:00Zからの指定したミリ秒数を使用したInstantインスタンスを取得


Sample.java
package com.sample;

import java.time.Instant;

public class Sample {
    public static void main(String[] args) {
        Instant instant1 = Instant.now();
        Instant instant2 = Instant.ofEpochSecond(1000000000L);
        Instant instant3 = Instant.ofEpochSecond(1000000000L, 1000000000L);
        Instant instant4 = Instant.ofEpochMilli(1000000000000L);

        System.out.println("現在のインスタント         : " + instant1);
        System.out.println("インスタント(秒)         : " + instant2);
        System.out.println("インスタント(秒・ナノ秒) : " + instant3);
        System.out.println("インスタント(ミリ秒)     : " + instant4);
    }
}
実行結果
現在のインスタント         : 2023-09-22T07:43:19.138Z
インスタント(秒)         : 2001-09-09T01:46:40Z
インスタント(秒・ナノ秒) : 2001-09-09T01:46:41Z
インスタント(ミリ秒)     : 2001-09-09T01:46:40Z


OffsetDateTime

時差(オフセット)を含んだ日付/時刻クラス

  • オフセット : 協定世界時(UTC)からの時差
    協定世界時 : 基準となる標準時


OffsetTimeクラス

オフセットを含む時刻を表すクラス


Sample.java
package com.sample;

import java.time.LocalTime;
import java.time.OffsetTime;
import java.time.ZoneOffset;

public class Sample {
    public static void main(String[] args) {
        ZoneOffset offset = ZoneOffset.of("+09:00");
        OffsetTime offsetTime = OffsetTime.of(LocalTime.now(), offset);
        System.out.println("オフセット付き時刻(アジア/東京) : " + offsetTime);
    }
}
実行結果
オフセット付き時刻(アジア/東京) : 14:12:43.080+09:00


OffsetDateTimeクラス

オフセットを含む日時を表すクラス


Sample.java
package com.sample;

import java.time.LocalDateTime;
import java.time.OffsetDateTime;
import java.time.ZoneOffset;

public class Sample {
    public static void main(String[] args) {
        ZoneOffset offset = ZoneOffset.of("+09:00");
        OffsetDateTime offsetDateTime = OffsetDateTime.of(LocalDateTime.now(), offset);
        System.out.println("オフセット : " + offset);
        System.out.println("オフセット付き日時(アジア/東京) : " + offsetDateTime);
    }
}
実行結果
オフセット : +09:00
オフセット付き日時(アジア/東京) : 2023-09-20T14:01:24.647+09:00


ZonedDateTime

タイムゾーンを含んだ日付/時刻クラス

  • タイムゾーン : 同一の標準時を使用している地域


ZoneIdクラス

タイムゾーンIDを表すクラス

タイムゾーンID取得方法
ZonedId defaultZoneId = ZoneId.systemDefault();     // デフォルトのゾーンIDを取得
ZonedId zoneId = ZoneId.of("America/Los_Angeles");  // 指定したIDからゾーンIDを取得
<主なタイムゾーンID>
地域 タイムゾーンID
JST 日本標準時 Asia/Tokyo
PST 米国西海岸標準時 America/Los_Angeles


ZonedDateTimeクラス

タイムゾーンを含む日時を表すクラス


Sample.java
package com.sample;

import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;

public class Sample {
    public static void main(String[] args) {
        ZonedDateTime zonedDateTime1 = ZonedDateTime.of(LocalDateTime.now(),ZoneId.systemDefault());
        ZonedDateTime zonedDateTime2 = ZonedDateTime.of(LocalDateTime.now(),ZoneId.of("America/Los_Angeles"));
	System.out.println("現在の日時(アジア/東京)           : " + zonedDateTime1);
	System.out.println("現在の日時(アメリカ/ロサンゼルス) : " + zonedDateTime2);
    }
}
実行結果
2023-09-20T13:50:05.718+09:00[Asia/Tokyo]
2023-09-20T13:50:05.719-07:00[America/Los_Angeles]


ZoneOffsetクラス

タイムゾーンに対するオフセットを表すクラス

オフセット取得方法
ZoneOffset offset = ZoneOffset.of("+09:00");
<ZoneOffsetクラスの定数>
定数 説明
UTC UTC用のタイムゾーン・オフセット


夏時間

明るい時間を有効に活用するために年2回行われる時間調整

  • 2016年の場合
    • 2016年の夏時間開始日時 : 2016年3月13日2時00分 EST
    • 2016年の夏時間終了日時 : 2016年11月6日2時00分 EST


Sample.java
package com.sample;

import java.time.LocalDateTime;
import java.time.Month;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.temporal.ChronoUnit;

public class Sample {
    public static void main(String[] args) {
        ZoneId zoneId = ZoneId.of("America/Los_Angeles");
        ZonedDateTime fromDateTime = ZonedDateTime.of(LocalDateTime.of(2016, Month.MARCH, 13, 0, 0, 0), zoneId);
        ZonedDateTime toDateTime = fromDateTime.plusHours(2L);

        System.out.println("夏時間開始前 : " + fromDateTime);
        System.out.println("夏時間開始後 : " + toDateTime);

        System.out.println("時間差 : " + ChronoUnit.HOURS.between(fromDateTime, toDateTime));
    }
}
実行結果
夏時間開始前 : 2016-03-13T00:00-08:00[America/Los_Angeles]
夏時間開始後 : 2016-03-13T03:00-07:00[America/Los_Angeles]
時間差 : 2


日付/時刻のフォーマット

DateTimeFormatterクラス

Date and Time API(日付/時刻API)のjava.time.formatパッケージで提供されるフォーマットクラス

<DateTimeFormatterクラスの定数>
定数 説明
ISO_DATE オフセット付きもしくはオフセットなし日付に
対し、書式設定や解析を行うフォーマッタ
2012-07-05
2012-07-05+04:00
ISO_TIME オフセット付きもしくはオフセットなしの時刻に
対し、書式設定や解析を行うフォーマッタ
13:04
13:04:10
13:04:10+04:00
ISO_DATE_TIME オフセット付きもしくはオフセットなしの日時に
対し、書式設定や解析を行うフォーマッタ
2012-07-05T13:04:10
2012-07-05T13:04:10+04:00
<DateTimeFormatterクラスのメソッド>
メソッド名 説明
static DateTimeFormatter
ofLocalizedDate(FormatStyle dateStyle)
ロケール固有の日付フォーマットを返す
static DateTimeFormatter
ofLocalizedTime(FormatStyle timeStyle)
ロケール固有の時間フォーマットを返す
static DateTimeFormatter
ofLocalizedDateTime(FormatStyle dateTimeStyle)
ロケール固有の日時フォーマットを返す
static DateTimeFormatter
ofPattern(String pattern)
指定されたパターンを使用したフォーマッタを返す
static DateTimeFormatter
ofPattern(String pattern, Locale locale)
指定されたパターンとロケールを使用したフォーマッタを返す
String format(TemporalAccessor temporal) このフォーマッタを使用して、指定された日付/時刻インスタンスを書式化した文字列を返す

FormatStyle列挙型

ローカライズされた日付、時間または日時フォーマッタのスタイルのEnumクラス

<FormatStyle列挙型のEnum定数>
Enum定数 説明
FULL もっとも多くの詳細を含むフルテキスト・スタイル 2023年9月25日 2時09分36秒 JST
LONG 多くの詳細を含むテキスト・スタイル 023/09/25 2:09:36 JST
MEDIUM いくらかの詳細を含むテキスト・スタイル 2023/09/25 2:09:36
SHORT 短いテキスト・スタイル 23/09/25 2:09
Sample.java
package com.sample;

import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.FormatStyle;

public class Sample {
    public static void main(String[] args) {
        ZonedDateTime zonedDateTime = ZonedDateTime.of(LocalDateTime.now(), ZoneId.systemDefault());

        DateTimeFormatter fullFmt = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.FULL);
        DateTimeFormatter longFmt = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.LONG);
        DateTimeFormatter midFmt = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.MEDIUM);
        DateTimeFormatter shortFmt = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.SHORT);

        System.out.println("FULL   : " + zonedDateTime.format(fullFmt));
        System.out.println("LONG   : " + zonedDateTime.format(longFmt));
        System.out.println("MEDIUM : " + zonedDateTime.format(midFmt));
        System.out.println("SHORT  : " + zonedDateTime.format(shortFmt));
    }
}
実行結果
FULL   : 2023年9月25日 2時09分36秒 JST
LONG   : 2023/09/25 2:09:36 JST
MEDIUM : 2023/09/25 2:09:36
SHORT  : 23/09/25 2:09


参考文献

  • 山本道子. オラクル認定資格教科書 Javaプログラマ Gold SE 8 (EXAMPRESS). 翔泳社. 2016.
  • 米山学. 徹底攻略 Java SE 8 Gold 問題集[1Z0-809]対応. 株式会社インプレス. 2018.

Discussion