【Java】Javaのjava.timeで日付・時刻を扱う基本と使い方

Java

こんにちは、かつコーチです。
「今日の日付を出したいだけなのに、DateCalendarのどっちを使えばいいの?」と迷ったことはありませんか。
今回はJava 21でも標準の日付・時刻ライブラリであるjava.time(日付や時刻を安全に扱うためのパッケージ)の基本を解説します。

java.timeとは?

なぜDateやCalendarを使わないのか

古いJavaにはjava.util.Datejava.util.Calendarという日付クラスがありましたが、これらには「月が0始まり」「スレッドセーフでない」「値を変更できてしまう」といった分かりにくい問題がありました。
そこでJava 8以降はjava.timeパッケージが標準になり、今もこちらを使うのが基本です。

java.timeの主要クラス

  • LocalDate(時刻を持たない日付):年月日だけを扱う
  • LocalTime(日付を持たない時刻):時分秒だけを扱う
  • LocalDateTime(日付と時刻の両方):年月日+時分秒を扱う
  • DateTimeFormatter(日付・時刻の書式を変換するクラス):文字列との相互変換に使う

用途に応じてクラスを使い分けるのが、java.timeを理解する最初のポイントです。

基本の書き方

現在日時の取得

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

public class DateTimeSample {
    public static void main(String[] args) {
        LocalDate today = LocalDate.now();
        LocalTime now = LocalTime.now();
        LocalDateTime dateTime = LocalDateTime.now();

        System.out.println(today);     // 例:2026-08-31
        System.out.println(now);       // 例:14:23:05.123
        System.out.println(dateTime);  // 例:2026-08-31T14:23:05.123
    }
}

now()メソッドを呼ぶだけで、現在の日付・時刻を取得できます。
LocalDateは年月日のみ、LocalDateTimeは時刻まで含む点が違いです。

日付の指定・加算・比較

import java.time.LocalDate;

LocalDate birthday = LocalDate.of(1990, 4, 1); // 年,月,日を指定
LocalDate nextWeek = LocalDate.now().plusWeeks(1); // 1週間後
LocalDate lastMonth = LocalDate.now().minusMonths(1); // 1ヶ月前

boolean isBefore = birthday.isBefore(LocalDate.now());
System.out.println(isBefore); // true

plusDaysplusMonthsminusYearsのようなメソッドで日付を加算・減算でき、isBeforeisAfterで前後関係を比較できます。
すべて新しいLocalDateインスタンスを返すイミュータブル(変更不可)な設計なので、元の値が勝手に変わる心配がありません。

文字列との相互変換(DateTimeFormatter)

import java.time.LocalDate;
import java.time.format.DateTimeFormatter;

LocalDate date = LocalDate.of(2026, 8, 31);
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy年MM月dd日");

String text = date.format(formatter);
System.out.println(text); // 2026年08月31日

LocalDate parsed = LocalDate.parse("2026-12-25");
System.out.println(parsed); // 2026-12-25

画面表示用に和暦っぽい形式にしたいときはDateTimeFormatter.ofPatternでパターンを指定します。
逆に文字列からLocalDateを作りたいときはparseを使いますが、フォーマットが一致しないと例外が発生するので注意が必要です。

よくあるつまずきポイント・エラー対処

文字列のフォーマット不一致でDateTimeParseException

実際に私が業務で日付をCSVから取り込む処理を書いたとき、次のコードで例外が発生しました。

// ❌Before:フォーマットを指定せずparseして例外発生
import java.time.LocalDate;

String csvDate = "2026/08/31";
LocalDate date = LocalDate.parse(csvDate); // 例外発生

このコードはjava.time.format.DateTimeParseException: Text '2026/08/31' could not be parsedという例外になります。
LocalDate.parseは引数なしだとyyyy-MM-dd形式しか受け付けないため、/区切りの文字列はそのままでは解析できません。

// ✅After:DateTimeFormatterで元の形式を明示する
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;

String csvDate = "2026/08/31";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy/MM/dd");
LocalDate date = LocalDate.parse(csvDate, formatter);
System.out.println(date); // 2026-08-31

外部から受け取る日付文字列を扱うときは、必ず元データの形式に合わせたDateTimeFormatterを用意する癖をつけましょう。

応用・一歩先の使い方

期間の差分を求める(Period・Duration)

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

LocalDate start = LocalDate.of(2026, 1, 1);
LocalDate end = LocalDate.of(2026, 8, 31);

Period period = Period.between(start, end);
System.out.println(period.getMonths() + "ヶ月" + period.getDays() + "日");

日付同士の差を求めたいときはPeriod(日付の差分を表すクラス)を使います。
時刻同士の差分(何時間何分か)を求めたいときは、同じ考え方でDurationクラスを使います。

タイムゾーンを扱う(ZonedDateTime)

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

ZonedDateTime tokyoTime = ZonedDateTime.now(ZoneId.of("Asia/Tokyo"));
ZonedDateTime nyTime = tokyoTime.withZoneSameInstant(ZoneId.of("America/New_York"));

System.out.println(tokyoTime);
System.out.println(nyTime);

海外向けサービスでタイムゾーンを扱う必要が出てきたら、LocalDateTimeではなくZonedDateTime(タイムゾーン情報付きの日時)に切り替えます。

まとめ

この記事のポイント

  • java.timeはLocalDateLocalTimeLocalDateTimeを用途に応じて使い分ける
  • すべてイミュータブルなので、加算・減算のメソッドは新しいインスタンスを返す
  • 文字列との変換はDateTimeFormatterでフォーマットを明示する
  • 差分計算にはPeriodDuration、タイムゾーンにはZonedDateTimeを使う

次に読むべき記事

  • ファイル入出力(java.nio.file)
  • Scannerで入力を受け取る

タグ: Java, 初心者向け, 標準ライブラリ

タイトルとURLをコピーしました