1. 同じ月内の差 (2026-05-01 から 2026-05-19 まで) は 18 日
  2. うるう年 2024 年の 1 月 1 日から 12 月 31 日までは 365 日
  3. 同じ日付同士の差は 0
  4. 引数の順番が逆 (未来 → 過去) の場合は負の値を返す
  5. 年をまたぐ差 (2025-12-31 から 2026-01-01) は 1 日
コース一覧
Java 中級:コレクション・Stream・例外処理
Duration で時間差を計算

Java 中級:コレクション・Stream・例外処理

コレクション、ジェネリクス、例外処理、Stream API、関数型インターフェース、日付処理、ファイル I/O、継承など Java の中級トピックを実践的に学べるコースです。Java の基礎文法とオブジェクト指向を理解している学習者を対象に、現場の Java コードを読み書きするための知識を補強します。約 16 時間 (1 日 30 分 × 32 日) で 64 レッスンを修了でき、修了後は Spring Boot や業務システム開発に必要な Java 力が身につきます。

1
コレクション基礎
01. ArrayList を使う5分
02. List を走査する5分
03. 要素の削除と検索5分
04. HashMap の基本5分
05. Map を走査する5分
06. Set で重複を排除5分
07. Collections クラスの便利メソッド5分
08. コレクション基礎 まとめクイズ5分
2
ジェネリクス
01. ジェネリッククラスを作る5分
02. ジェネリックメソッド5分
03. 境界型パラメータ5分
04. ワイルドカード ?5分
05. Pair<K,V> を作る5分
06. ジェネリクス まとめクイズ5分
3
例外処理
01. try-catch で例外をつかむ5分
02. 複数の catch ブロック5分
03. throws と例外の伝播5分
04. 独自の例外を作る5分
05. try-with-resources5分
06. finally ブロック5分
07. 例外処理 まとめクイズ5分
4
Stream API
01. Stream を作る5分
02. filter で絞り込む5分
03. map で変換する5分
04. reduce で集約する5分
05. collect で集める5分
06. sorted で並び替え5分
07. distinct で重複排除5分
08. limit と skip5分
09. 並列ストリーム5分
10. Stream API まとめクイズ5分
5
関数型インターフェース
01. ラムダ式の基本5分
02. メソッド参照 ::5分
03. Function インターフェース5分
04. Predicate インターフェース5分
05. Consumer と Supplier5分
06. BiFunction と 2 引数の関数5分
07. 関数型インターフェース まとめクイズ5分
6
文字列操作
01. String.format で書式化5分
02. StringBuilder で連結5分
03. 正規表現の基本5分
04. split と join5分
05. 文字列操作 まとめクイズ5分
7
日付と時刻
01. LocalDate で日付を扱う5分
02. LocalDateTime で時刻も扱う5分
03. Duration で時間差を計算5分
04. 日付の書式化とパース5分
05. 日付の加減算5分
06. 日付と時刻 まとめクイズ5分
8
ファイル I/O
01. Files でファイルに書き込む5分
02. ファイルを行単位で読む5分
03. Path でファイルパスを扱う5分
04. BufferedReader と Stream API5分
05. ファイルの存在確認と削除5分
06. ファイル I/O まとめクイズ5分
9
継承とポリモーフィズム
01. extends で継承する5分
02. super で親を呼ぶ5分
03. メソッドのオーバーライド5分
04. abstract で抽象クラス5分
05. interface で契約を定義5分
06. default メソッド5分
07. instanceof と型パターン5分
08. ポリモーフィズムを活かす5分
09. 継承とポリモーフィズム まとめクイズ5分

Duration で時間差を計算

日数の差を引き算で出すと、月をまたいだ瞬間に合わなくなる

「登録から 30 日たった人にメールを送る」「予約日まであと何日か表示する」。日付の差を数える処理は、業務アプリでいくらでも出てきます。ところが 日 の値どうしを引き算する方法は、同じ月の中でしか通用しません。月をまたげば月の長さを足す必要があり、年をまたげばうるう年かどうかまで自分で判定するはめになります。

java.time には、2 点間の差を単位ごとに数えてくれる ChronoUnit があります。DAYS HOURS MINUTES MONTHS YEARS といった単位を選び、between に始点と終点を渡すだけです。

Java

import java.time.LocalDate; import java.time.temporal.ChronoUnit; public class Demo { public static void main(String[] args) { LocalDate open = LocalDate.of(2026, 4, 1); LocalDate deadline = LocalDate.of(2026, 5, 19); long days = ChronoUnit.DAYS.between(open, deadline); System.out.println(days); // 48 } }

4 月が 30 日までであることも、月がまたがっていることも、こちら側では一切考えていません。うるう年をまたいでも同じように正しい値が返ります。

3 時間半のはずが 3 と返ってくる

between は「その単位が何回まるごと入るか」を数えるので、端数は切り捨てられます。9 時から 12 時 30 分までを HOURS で聞くと 3 です。

Java

import java.time.LocalDateTime; import java.time.temporal.ChronoUnit; LocalDateTime start = LocalDateTime.of(2026, 4, 1, 9, 0); LocalDateTime end = LocalDateTime.of(2026, 4, 1, 12, 30); System.out.println(ChronoUnit.MINUTES.between(start, end)); // 210 System.out.println(ChronoUnit.HOURS.between(start, end)); // 3

3.5 が欲しいわけではなく「何時間何分か」を知りたいのなら、細かい単位で取ってから自分で組み立てます。上の例なら 210 分を 60 で割って商と余りを出せば、3 時間 30 分になります。

引数を入れ替えると符号が反転する

between(start, end) が返すのは end から start を引いた値です。つまり start のほうが未来なら結果は負になります。

Java

LocalDate open = LocalDate.of(2026, 4, 1); LocalDate deadline = LocalDate.of(2026, 5, 19); System.out.println(ChronoUnit.DAYS.between(deadline, open)); // -48

これは不具合ではなく仕様です。「締め切りを過ぎているかどうか」を判定したいなら符号がそのまま答えになりますし、単に日数だけ知りたいなら Math.abs で絶対値を取ります。過去か未来かの情報を捨てる前に、本当に捨てていいのか一度考えてください。

解説

between の戻り値は long です。int の変数に入れたいときは (int) で明示的にキャストします。int は約 21 億まで扱えて、日数に直すと 580 万年を超えるので、日付の差であふれる心配はまずありません。

やってみよう

Solution.daysBetween(int year1, int month1, int day1, int year2, int month2, int day2) を完成させます。

  1. import java.time.LocalDate; と import java.time.temporal.ChronoUnit; を書く
  2. 受け取った 6 つの数値から LocalDate を 2 つ作る
  3. 日数の差を求め、int に変換して return する

daysBetween(2026, 5, 1, 2026, 5, 19) は 18、daysBetween(2026, 5, 19, 2026, 5, 1) は -18 です。順番を逆にしたときに負の値が返ることまで確認されるので、絶対値を取ってはいけません。

要件

  1. ファイル先頭で import java.time.LocalDate; と import java.time.temporal.ChronoUnit; を書くこと
  2. LocalDate.of(year, month, day) を 2 回呼んで 2 つの LocalDate を作ること
  3. ChronoUnit.DAYS.between(d1, d2) の戻り値 (long) を (int) でキャストして返すこと

入出力例

daysBetween(2026, 5, 1, 2026, 5, 19) → 18 daysBetween(2024, 1, 1, 2024, 12, 31) → 365 daysBetween(2026, 5, 19, 2026, 5, 19) → 0 daysBetween(2026, 5, 19, 2026, 5, 1) → -18 daysBetween(2025, 12, 31, 2026, 1, 1) → 1

ヒント

`ChronoUnit.DAYS.between(d1, d2)` は `d2 - d1` を返します。引数順を逆にすると符号が反転します

`Period.between(d1, d2).getDays()` は「年月を除いた日」の値を返すので、合計日数を取りたい今回の課題には不向きです。必ず `ChronoUnit.DAYS.between` を使いましょう

戻り値の型は `int` ですが `ChronoUnit.DAYS.between` の戻り値は `long` なので、`return (int) ChronoUnit.DAYS.between(d1, d2);` のようにキャストが必要です

生田 陸人
監修生田 陸人
ゆめさくエンジニア / 現役ソフトウェアエンジニア監修者プロフィールを見る →
編集 ゆめさく編集部·公開 2026/05/19·更新 2026/08/26

関連レッスン

  • 日付の書式化とパース

    DateTimeFormatter.ofPattern() で LocalDate を任意の書式に変換し、逆に文字列から日付へ parse する方法を学ぼう。

  • 日付の加減算

    LocalDate の plusDays や minusDays を使って日付を前後に動かす方法を学び、不変オブジェクトとしての扱い方を身につけよう。

  • 日付と時刻 まとめクイズ

    Java 8 で導入された java.time パッケージ (LocalDate / LocalDateTime / Duration / Period / DateTimeFormatter / 加減算) の総まとめ。不変性 (immutable)、ChronoUnit、parse/format の対称性など実務頻出のポイントを 4 択クイズで確認する。

  • Files でファイルに書き込む

    Java の標準ライブラリ `java.nio.file.Files` を使って、ファイルへの書き込みと読み込みをわずか数行で実現する方法を学ぼう。

このレッスンに出てくる用語

意味があいまいなまま進んだ語は、ここから読み直せます。

  • 処理計算や代入を表す長方形
  • 引数位置引数=順番で渡す。
  • 戻り値呼び出し元への返答を表す点線矢印
  • 変数データに名前をつけて参照する仕組み
  • instanceof「このオブジェクトの実際の型は何か」を確認 → 安全に変換
main.java
学習モード
エディタを読み込んでいます

メモ

Duration で時間差を計算

⌘S で保存