Java でシステム日付などの時間を扱うクラスには、「Date」クラスと「Calendar」クラス、さらには Java8で新たに追加された「java.time」パッケージとして追加されたクラス群の3つに分類されます。
この記事では、Java でシステム日付を取得する方法と、「Date」「Calendar」「LocalDateTime」クラスの特徴や使い方を解説していきます。日付処理は、プログラミングにおいて必須の知識と言えるため、是非とも覚えておきましょう。
システム日付を取得する
まずは、「Date」「Calendar」「LocalDateTime」クラスのそれぞれで、システム日付を取得する方法を確認しましょう。
Dateクラスで取得
Date クラスの場合、引数なしのコンストラクタで Dateクラスを作成することで、現在時刻を格納したインスタンスを取得できます。
Date now = new Date();
Calendarクラスで取得
Calendar クラスでシステム日付を取得する場合は、Calendar.getInstanceメソッドを使用します。戻り値には現在時刻を格納した Calendar クラスのインスタンスが返ります。
Calendar cal = Calendar.getInstance();
LocalDateTimeで取得
LocalDateTime クラスは、 Java8 で「java.time」パッケージに追加された新しいクラスです。
LocalDateTime クラスでシステム日付を取得する場合は、専用のメソッドである nowを使用します。
LocalDateTime now = LocalDateTime.now();
Dateクラスは非推奨?
Java のDate クラスは、Java が登場した頃から存在する最も歴史が長いクラスです。
その後、Calendar クラスや java.timeパッケージが追加され、 Java8 では次の表の通り Date クラスの多くのメソッドが非推奨となり、将来的にはメソッド自体が削除され使用できなくなることが予定されています。
<非推奨のメソッド>
getDate(), getDay(), getHours(), getMinutes(), getMonth(), getSeconds(), getTimezoneOffset(), getYear(), parse(String), setDate(int), setHours(int), setMinutes(int), setMonth(int), setSeconds(int seconds), setYear(int), toGMTString(), toLocaleString(), UTC(int year, int month, int date, int hrs, int min, int sec)
<まだ使えるメソッド>
after(Date), before(Date), clone(), compareTo(Date), equals(Object), getTime(), setTime(long)
このように、日付を取得・操作するためのメソッドのほとんどが非推奨になっている状況で、Date クラス自体が非推奨と言っってもいい状況で、公式の JavaDocでも次のように述べられています。
JDK 1.1からは、日付と時間フィールドの間の変換にはCalendarクラスを、日付文字列のフォーマットと構文解析にはDateFormatクラスをそれぞれ使用する必要があります。Dateの対応するメソッドは非推奨です。
日付を文字列にフォーマットする
Calendar や LocalDateTimeのクラスを書式指定して文字列にする場合は「SimpleDateFormat」または「DateTimeFormatter」クラスを使用します。
SimpleDateFormat
まずは、SimpleDateFormat クラスで Calendar のインスタンスを書式指定して文字列にする方法を見ていきましょう。
import java.util.Calendar;
import java.text.SimpleDateFormat;
class Main {
public static void main(String[] args) {
//現在時刻でカレンダーのインスタンスを取得
Calendar cal = Calendar.getInstance();
//SimpleDateFormatで書式を指定
SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd");
//Calendarの日付をSimpleDateFormatで指定した書式で文字列に変換
System.out.println(sdf.format(cal.getTime()));
}
}
このように、SimpleDateFormat のコンストラクタで日付を文字列にフォーマットする時の書式を指定し、SimpleDateFormat#format メソッドで実際に日付のインスタンスを文字列に変換します。
SimpleDateFormat クラスのコンストラクタに指定するフォーマットパターンは、Java の公式ドキュメントで詳しく紹介されていますので、以下のリンクを参照してください。
SimpleDateFormat
ちなみに、SimpleDateFormatクラスはスレッドセーフではないため、マルチスレッド環境で共有の変数とし、同時に使用すると正しい動作をしないため注意が必要です。
DateTimeFormatter
別のフォーマットするクラスとして、Java8 で追加された DateTimeFormatter クラスがあります。こちらはスレッドセーフなクラスであり、パフォーマンスにも優れているため、Java8 以降のバージョンを使用して開発を行なっている場合は、基本的にはこちらのクラスを使用した方がよいでしょう。
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
class Main {
public static void main(String[] args) throws DateTimeParseException {
// 書式を指定してDateTimeFormatterを取得
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy/MM/dd");
// 書式を指定してLocalDateTimeのインスタンスを作成する
LocalDateTime dt = LocalDateTime.now();
// システム日付を、DateTimeFormatterで指定したフォーマットで文字列に変換
String str = LocalDateTime.now().format(dtf);
System.out.println(str);
}
}
タイムゾーンを考慮したシステム時刻を取得
ご存知の通り地球には時差があり、ある同じ瞬間でも、地域(タイムゾーン)よって時差があり当然、システム日付も異なります。Java でタイムゾーンを意識した日付を扱う場合は、ZonedDateTime クラスを用います。
次のサンプルコードは、協定世界時(UTC)、東京、太平洋標準時のタイムゾーンそれぞれで現在日時を取得例です。
import java.time.*;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
public class Main {
public static void main(String[] args) throws DateTimeParseException {
DateTimeFormatter dtf = DateTimeFormatter.ISO_OFFSET_DATE_TIME;
// 協定世界時(UTC)での現在時刻を取得
ZonedDateTime utcNow = ZonedDateTime.now(ZoneId.of("Z"));
System.out.println(utcNow.format(dtf));
// 東京の現在時刻を取得
ZonedDateTime tokyoNow = ZonedDateTime.now(ZoneId.of("Asia/Tokyo"));
System.out.println(tokyoNow.format(dtf));
// 太平洋標準時(米国およびカナダ)
ZonedDateTime americaLosNow = ZonedDateTime.now(ZoneId.of("America/Los_Angeles"));
System.out.println(americaLosNow.format(dtf));
}
}
上のコードを実行した結果は次のようになります。東京はUTC+9時間、太平洋標準時はUTC-7時間の時差で現在日時が取得されているのが分かります。
2021-07-13T14:04:34.776251214Z
2021-07-13T23:04:34.79787482+09:00
2021-07-13T07:04:34.800231561-07:00
LocalDateTime クラスは、その名の通りローカル時間を管理するクラスです。タイムゾーンや時差などの情報も表現したい場合は、同じ「java.time」パッケージに存在する ZonedDateTimeクラスや、OffsetDateTimeを使用します。