Skip to main content

日時操作

この章では、日付や時刻を扱うための 日時操作 について学ぶ。 Java 8で導入されたjava.timeパッケージを使うことで、日付や時刻を簡単に扱えるようになる。


この章で得られるスキル:

  • ✅ 日付や時刻を正確に扱うプログラムが書ける
  • ✅ 予約システムや期限管理の機能が実装できる
  • ✅ 日付の計算や比較が簡単にできる
  • ✅ ユーザーに見やすい形式で日時を表示できる

なぜこの技術が必要か

日時操作がないとどうなるか?

日付や時刻を扱うプログラムは多い(予約システム、勤怠管理、スケジュール管理など)。 適切な日時操作の仕組みがないと、日付の計算や比較が複雑になる。

例:

// 今日の日付を取得
LocalDate today = LocalDate.now();
System.out.println("今日: " + today);

// 1週間後の日付を計算
LocalDate nextWeek = today.plusDays(7);
System.out.println("1週間後: " + nextWeek);

// 年齢を計算
LocalDate birthday = LocalDate.of(2000, 5, 15);
Period age = Period.between(birthday, today);
System.out.println("年齢: " + age.getYears() + "歳");

日時操作の仕組みを使うことで、複雑な日付計算を簡単に実現できる。


1. java.timeパッケージとは

java.timeの概要

java.timeパッケージ は、**Java 8で導入された新しい日時APIで、日付や時刻を扱うためのクラス群である。

主なクラス

クラス説明
LocalDate日付(年月日)2024-01-15
LocalTime時刻(時分秒)14:30:00
LocalDateTime日時(年月日時分秒)2024-01-15T14:30:00
Period期間(日付の差)3年2ヶ月5日
Duration時間(時刻の差)2時間30分

2. LocalDate(日付)

LocalDateとは

LocalDate は、日付(年月日)を表すクラス である。 時刻情報は持たない。

基本的な使い方

import java.time.LocalDate;

// 今日の日付
LocalDate today = LocalDate.now();

// 特定の日付を作成
LocalDate date = LocalDate.of(2024, 1, 15); // 2024年1月15日

// 日付の要素を取得
int year = date.getYear(); // 年
int month = date.getMonthValue(); // 月(1-12)
int day = date.getDayOfMonth(); // 日

実行してみよう:

import java.time.LocalDate; public class Main { public static void main(String[] args) { // 今日の日付 LocalDate today = LocalDate.now(); System.out.println("今日: " + today); // 特定の日付を作成 LocalDate birthday = LocalDate.of(2000, 5, 15); System.out.println("誕生日: " + birthday); // 日付の要素を取得 System.out.println("\n今日の情報:"); System.out.println("年: " + today.getYear()); System.out.println("月: " + today.getMonthValue()); System.out.println("日: " + today.getDayOfMonth()); System.out.println("曜日: " + today.getDayOfWeek()); // 日付の比較 boolean isBefore = birthday.isBefore(today); System.out.println("\n誕生日は今日より前か: " + isBefore); } }

やってみよう:

  • 自分の誕生日を設定して、今日との比較をしてみよう

日付の計算

LocalDate today = LocalDate.now();

// 日付の加算
LocalDate tomorrow = today.plusDays(1); // 1日後
LocalDate nextWeek = today.plusWeeks(1); // 1週間後
LocalDate nextMonth = today.plusMonths(1); // 1ヶ月後
LocalDate nextYear = today.plusYears(1); // 1年後

// 日付の減算
LocalDate yesterday = today.minusDays(1); // 1日前
LocalDate lastWeek = today.minusWeeks(1); // 1週間前

実行してみよう:

import java.time.LocalDate; public class Main { public static void main(String[] args) { LocalDate today = LocalDate.now(); System.out.println("今日: " + today); // 日付の加算 System.out.println("\n未来の日付:"); System.out.println("明日: " + today.plusDays(1)); System.out.println("1週間後: " + today.plusWeeks(1)); System.out.println("1ヶ月後: " + today.plusMonths(1)); System.out.println("1年後: " + today.plusYears(1)); // 日付の減算 System.out.println("\n過去の日付:"); System.out.println("昨日: " + today.minusDays(1)); System.out.println("1週間前: " + today.minusWeeks(1)); System.out.println("1ヶ月前: " + today.minusMonths(1)); System.out.println("1年前: " + today.minusYears(1)); // 複数の操作を組み合わせ LocalDate future = today.plusMonths(2).minusDays(5); System.out.println("\n2ヶ月後の5日前: " + future); } }

やってみよう:

  • 100日後の日付を計算してみよう
よくあるエラー

LocalDateイミュータブル(変更不可)である。 plusDays()などのメソッドは、元のオブジェクトを変更せず、新しいオブジェクトを返す。

LocalDate date = LocalDate.now();
date.plusDays(1); // これだけでは date は変わらない!
System.out.println(date); // 元の日付のまま

LocalDate newDate = date.plusDays(1); // 新しいオブジェクトを受け取る
System.out.println(newDate); // 1日後の日付

3. LocalTime(時刻)

LocalTimeとは

LocalTime は、時刻(時分秒)を表すクラス である。 日付情報は持たない。

基本的な使い方

import java.time.LocalTime;

// 現在の時刻
LocalTime now = LocalTime.now();

// 特定の時刻を作成
LocalTime time = LocalTime.of(14, 30); // 14:30
LocalTime time2 = LocalTime.of(14, 30, 45); // 14:30:45

// 時刻の要素を取得
int hour = time.getHour(); // 時
int minute = time.getMinute(); // 分
int second = time.getSecond(); // 秒

実行してみよう:

import java.time.LocalTime; public class Main { public static void main(String[] args) { // 現在の時刻 LocalTime now = LocalTime.now(); System.out.println("現在の時刻: " + now); // 特定の時刻を作成 LocalTime openTime = LocalTime.of(9, 0); // 開店時刻 LocalTime closeTime = LocalTime.of(18, 0); // 閉店時刻 System.out.println("\n営業時間:"); System.out.println("開店: " + openTime); System.out.println("閉店: " + closeTime); // 時刻の比較 boolean isOpen = now.isAfter(openTime) && now.isBefore(closeTime); System.out.println("\n現在営業中か: " + isOpen); // 時刻の計算 LocalTime lunchTime = openTime.plusHours(3); // 開店3時間後 System.out.println("ランチタイム: " + lunchTime); } }

やってみよう:

  • 現在時刻が営業時間内かどうかを判定するプログラムを改良してみよう

4. LocalDateTime(日時)

LocalDateTimeとは

LocalDateTime は、日付と時刻の両方を表すクラス である。

基本的な使い方

import java.time.LocalDateTime;

// 現在の日時
LocalDateTime now = LocalDateTime.now();

// 特定の日時を作成
LocalDateTime dateTime = LocalDateTime.of(2024, 1, 15, 14, 30);

// 要素を取得
int year = dateTime.getYear();
int hour = dateTime.getHour();

実行してみよう:

import java.time.LocalDateTime; public class Main { public static void main(String[] args) { // 現在の日時 LocalDateTime now = LocalDateTime.now(); System.out.println("現在: " + now); // イベントの日時を作成 LocalDateTime eventStart = LocalDateTime.of(2024, 12, 25, 19, 0); System.out.println("\nイベント開始: " + eventStart); // 日時の計算 LocalDateTime eventEnd = eventStart.plusHours(2); // 2時間後 System.out.println("イベント終了: " + eventEnd); // 日時の比較 boolean isUpcoming = eventStart.isAfter(now); System.out.println("\nイベントは未来か: " + isUpcoming); // 複雑な計算 LocalDateTime reminderTime = eventStart.minusDays(1).minusHours(12); System.out.println("リマインダー送信時刻: " + reminderTime); } }

やってみよう:

  • イベントまでの残り日数を表示するコードを追加してみよう

5. 期間の計算

Period(日付の期間)

Period は、日付の期間(年月日の差)を表すクラス である。

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

LocalDate start = LocalDate.of(2020, 1, 1);
LocalDate end = LocalDate.of(2024, 3, 15);

Period period = Period.between(start, end);
int years = period.getYears(); // 年
int months = period.getMonths(); // 月
int days = period.getDays(); // 日

実行してみよう:

import java.time.LocalDate; import java.time.Period; public class Main { public static void main(String[] args) { LocalDate today = LocalDate.now(); LocalDate birthday = LocalDate.of(2000, 5, 15); // 年齢を計算 Period age = Period.between(birthday, today); System.out.println("誕生日: " + birthday); System.out.println("今日: " + today); System.out.println("年齢: " + age.getYears() + "歳" + age.getMonths() + "ヶ月" + age.getDays() + "日"); // プロジェクトの期間 LocalDate projectStart = LocalDate.of(2024, 1, 1); LocalDate projectEnd = LocalDate.of(2024, 6, 30); Period projectDuration = Period.between(projectStart, projectEnd); System.out.println("\nプロジェクト期間:"); System.out.println("開始: " + projectStart); System.out.println("終了: " + projectEnd); System.out.println("期間: " + projectDuration.getMonths() + "ヶ月" + projectDuration.getDays() + "日"); } }

やってみよう:

  • 自分の誕生日から今日までの期間を計算してみよう

Duration(時刻の期間)

Duration は、時刻の期間(時間の差)を表すクラス である。

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

LocalTime start = LocalTime.of(9, 0);
LocalTime end = LocalTime.of(17, 30);

Duration duration = Duration.between(start, end);
long hours = duration.toHours(); // 時間
long minutes = duration.toMinutes(); // 分

実行してみよう:

import java.time.LocalTime; import java.time.Duration; public class Main { public static void main(String[] args) { LocalTime workStart = LocalTime.of(9, 0); LocalTime workEnd = LocalTime.of(18, 0); LocalTime lunchStart = LocalTime.of(12, 0); LocalTime lunchEnd = LocalTime.of(13, 0); // 勤務時間を計算 Duration workDuration = Duration.between(workStart, workEnd); Duration lunchDuration = Duration.between(lunchStart, lunchEnd); Duration actualWorkDuration = workDuration.minus(lunchDuration); System.out.println("勤務開始: " + workStart); System.out.println("勤務終了: " + workEnd); System.out.println("\n総勤務時間: " + workDuration.toHours() + "時間"); System.out.println("ランチ時間: " + lunchDuration.toHours() + "時間"); System.out.println("実働時間: " + actualWorkDuration.toHours() + "時間"); System.out.println("実働時間(分): " + actualWorkDuration.toMinutes() + "分"); } }

やってみよう:

  • 休憩時間を複数回設定して、実働時間を計算してみよう

6. 日時のフォーマット

DateTimeFormatterとは

DateTimeFormatter は、日時を文字列にフォーマットしたり、文字列を日時にパースする クラスである。

フォーマット(日時 → 文字列)

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

LocalDate date = LocalDate.now();

// 定義済みフォーマット
String str1 = date.format(DateTimeFormatter.ISO_DATE); // 2024-01-15

// カスタムフォーマット
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy年MM月dd日");
String str2 = date.format(formatter); // 2024年01月15日

パース(文字列 → 日時)

String dateString = "2024-01-15";
LocalDate date = LocalDate.parse(dateString);

String dateString2 = "2024年01月15日";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy年MM月dd日");
LocalDate date2 = LocalDate.parse(dateString2, formatter);

実行してみよう:

import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; public class Main { public static void main(String[] args) { LocalDateTime now = LocalDateTime.now(); // 様々なフォーマットで表示 System.out.println("デフォルト: " + now); DateTimeFormatter formatter1 = DateTimeFormatter.ofPattern("yyyy年MM月dd日 HH時mm分"); System.out.println("日本語: " + now.format(formatter1)); DateTimeFormatter formatter2 = DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss"); System.out.println("スラッシュ: " + now.format(formatter2)); DateTimeFormatter formatter3 = DateTimeFormatter.ofPattern("MM-dd-yyyy hh:mm a"); System.out.println("アメリカ式: " + now.format(formatter3)); // パース(文字列から日時へ) System.out.println("\nパースの例:"); String dateString = "2024-12-25 19:00:00"; DateTimeFormatter parseFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); LocalDateTime parsedDate = LocalDateTime.parse(dateString, parseFormatter); System.out.println("元の文字列: " + dateString); System.out.println("パース後: " + parsedDate); } }

やってみよう:

  • 自分でフォーマットパターンを作成して、様々な形式で日時を表示してみよう

主なフォーマットパターン

パターン意味
yyyy年(4桁)2024
MM月(2桁)01, 12
dd日(2桁)01, 31
HH時(24時間制)00-23
mm00-59
ss00-59
a午前/午後AM, PM
よくあるエラー

月は MM、分は mm で表す。大文字小文字を間違えないように注意が必要である。

// ❌ 間違い
DateTimeFormatter.ofPattern("yyyy-mm-dd"); // mmは分になってしまう

// ✅ 正しい
DateTimeFormatter.ofPattern("yyyy-MM-dd"); // MMが月

まとめ

この章では、日時操作 について学んだ。

学んだ内容

  • java.timeパッケージ で日付や時刻を扱える
  • LocalDate で日付(年月日)を扱える
  • LocalTime で時刻(時分秒)を扱える
  • LocalDateTime で日時(年月日時分秒)を扱える
  • Period で日付の期間を計算できる
  • Duration で時刻の期間を計算できる
  • DateTimeFormatter で日時のフォーマット・パースができる
  • 日時オブジェクトは イミュータブル である

これで基礎編は完了

Java基礎編の全16章を完了した。 次のステップでは、これらの知識を活用して、Webアプリケーション開発(Spring Framework)やデータベース操作(SQL)を学んでいく。


演習

LocalDate、LocalTime、LocalDateTimeの違いについて、正しい説明を選べ。

正解

D. LocalDateは日付のみ、LocalTimeは時刻のみ、LocalDateTimeは日付と時刻の両方を扱う

解説

Java 8で導入された日時APIの3つの主要クラス:

クラス扱う情報
LocalDate日付のみ2024-04-01
LocalTime時刻のみ14:30:00
LocalDateTime日付と時刻2024-04-01T14:30:00

DateTimeFormatterの役割として最も適切なものを選べ。

DateTimeFormatterは日時オブジェクトと文字列を相互に変換する。ofPattern("yyyy/MM/dd") で表示形式を指定できる。

正解

D. 日時オブジェクトを指定した形式の文字列に変換したり、文字列を日時オブジェクトに変換する

解説

DateTimeFormatterは日時の フォーマット(整形)パース(解析) を行うクラスである。format() で日時を文字列に変換し、parse() で文字列を日時に変換する。ofPattern("yyyy年MM月dd日") のようにパターンを指定できる。

以下のコードの空欄を埋めて、今日の日付を取得して表示するプログラムを完成させよ。

import java.time.LocalDate; LocalDate today =
; System.out.println("今日の日付: " + today);

解答例
LocalDate.now()
解説

LocalDate.now() で現在の日付を取得できる。now() はstaticメソッドで、new は使わない。LocalDate.of(2024, 4, 1) のように特定の日付を作成することもできる。

以下のコードの空欄を埋めて、現在時刻を取得して表示するプログラムを完成させよ。

import java.time.LocalTime; LocalTime now =
; System.out.println("現在時刻: " + now);

解答例
LocalTime.now()
解説

LocalTime.now() で現在の時刻を取得できる。LocalTime.of(14, 30) で特定の時刻(14時30分)を作成することもできる。

以下のコードの空欄を埋めて、現在の日時を取得して表示するプログラムを完成させよ。

import java.time.LocalDateTime; LocalDateTime now =
; System.out.println("現在日時: " + now);

解答例
LocalDateTime.now()
解説

LocalDateTime.now() で現在の日付と時刻を取得できる。LocalDateTime.of(2024, 4, 1, 14, 30) のように日付と時刻を指定して作成することも可能である。toLocalDate()toLocalTime() で日付部分と時刻部分を個別に取得できる。

以下のコードの空欄を埋めて、今日から7日後と3日前の日付を求めるプログラムを完成させよ。

LocalDate today = LocalDate.now(); // 7日後 LocalDate nextWeek =
; // 3日前 LocalDate threeDaysAgo =
;

plusDays(), minusDays() で日数の加算・減算ができる。同様に plusMonths(), plusYears() なども使える。元のオブジェクトは変更されず、新しいオブジェクトが返される点に注意。

解答例
today.plusDays(7) / today.minusDays(3)
解説

日付の加算は plusDays(), plusMonths(), plusYears() で行う。減算は minusDays(), minusMonths(), minusYears() を使う。元のオブジェクトは変更されず、新しいオブジェクトが返される(イミュータブル)。

以下のプログラムを完成させよ。

要件

  • 2024年1月1日と2024年12月31日の差を日数で計算して表示する
  • ChronoUnit.DAYS.between() を使用する
import java.time.LocalDate; import java.time.temporal.ChronoUnit; public class Main { public static void main(String[] args) { // ここにコードを書いてください } }

ChronoUnit.DAYS.between(開始日, 終了日) で2つの日付の差を日数で取得できる。Period.between() を使うと年・月・日単位で差を取得できる。

解説

解答例

LocalDate start = LocalDate.of(2024, 1, 1);
LocalDate end = LocalDate.of(2024, 12, 31);

long days = ChronoUnit.DAYS.between(start, end);
System.out.println("日数の差: " + days + "日");

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

ChronoUnit.DAYS.between() は日数を long で返す。Period.between() は年月日の差を Period オブジェクトで返し、getYears(), getMonths(), getDays() で個別に取得できる。

以下のコードの空欄を埋めて、日付を「yyyy/MM/dd」形式で表示するプログラムを完成させよ。

import java.time.LocalDate; import java.time.format.DateTimeFormatter; LocalDate today = LocalDate.now(); DateTimeFormatter formatter =
; System.out.println(today.format(formatter));

DateTimeFormatter.ofPattern("yyyy年MM月dd日") でフォーマットを指定する。yyyy=年4桁、MM=月2桁、dd=日2桁、HH=時2桁、mm=分2桁である。

解答例
DateTimeFormatter.ofPattern("yyyy/MM/dd")
解説

DateTimeFormatter.ofPattern() で日時の表示形式を指定する。主なパターン文字:

パターン意味
yyyy年(4桁)2024
MM月(2桁)04
dd日(2桁)01
HH時(24時間)14
mm30

today.format(formatter) で指定した形式の文字列に変換される。

PeriodとDurationの違いについて、正しい説明を選べ。

Periodは日付ベース(年・月・日)、Durationは時間ベース(時・分・秒)の差を表す。それぞれ対応するクラスが異なる。

正解

D. Periodは年月日の差を表し、Durationは時分秒の差を表す

解説
  • Period: 年・月・日 単位の差を表す(LocalDate と一緒に使う)
  • Duration: 時・分・秒 単位の差を表す(LocalTime, LocalDateTime と一緒に使う)

例:Period.between(date1, date2) で日付の差、Duration.between(time1, time2) で時刻の差を取得する。

Java 8の日時オブジェクト(LocalDate等)の変更可能性について、正しい説明を選べ。

plusDays() などのメソッドは元のオブジェクトを変更するのか、新しいオブジェクトを返すのかに注目しよう。

正解

D. 日時オブジェクトはイミュータブル(不変)で、plusDays()などは新しいオブジェクトを返す

解説

Java 8の日時クラス(LocalDate, LocalTime, LocalDateTime等)はすべて イミュータブル(不変) である。plusDays()minusHours() などのメソッドは 元のオブジェクトを変更せず、新しいオブジェクトを返す

LocalDate today = LocalDate.now();
LocalDate tomorrow = today.plusDays(1);
// today は変更されない(todayは今日のまま)

この性質により、意図しない変更を防ぎ、スレッドセーフに使用できる。