Period と Duration をざっくり一言でいうと
Period と Duration は、どちらも「時間の長さ」を表すクラスですが、
何を基準にしているかがまったく違います。
Period… 年・月・日ベース(カレンダー的な「◯年◯か月◯日」)Duration… 時・分・秒・ナノ秒ベース(ストップウォッチ的な「◯時間◯分◯秒」)
たとえば、
「このプロジェクトは 2 年 3 か月 10 日かかる」
→ Period が得意な世界
「処理時間は 3 秒 200 ミリ秒だった」
→ Duration が得意な世界
というイメージです。
「日付の差」を扱いたいのか、「時刻の差」を扱いたいのか。
ここを意識すると、どちらを使うべきか迷いにくくなります。
Period:年・月・日で扱う“カレンダー的な期間”
Period の基本イメージと生成方法
Period は「◯年◯か月◯日」という単位で期間を扱います。
使う対象は LocalDate(日付だけ)の世界が基本です。
代表的な生成方法は 2 つあります。
import java.time.LocalDate;
import java.time.Period;
public class PeriodBasic {
public static void main(String[] args) {
// 1. 直接「2年3か月10日」という期間を作る
Period p1 = Period.of(2, 3, 10);
System.out.println(p1); // P2Y3M10D
// 2. 2つの LocalDate の差から作る
LocalDate start = LocalDate.of(2025, 1, 1);
LocalDate end = LocalDate.of(2027, 4, 11);
Period p2 = Period.between(start, end);
System.out.println(p2); // P2Y3M10D のような感じ
}
}
JavaPeriod.between(start, end) は「start から end までの差」を「年・月・日」に分解したものです。
マイナス方向(start > end)の場合は、負の値を持つ Period が返ります。
Period の中身を取り出す
LocalDate start = LocalDate.of(2025, 1, 1);
LocalDate end = LocalDate.of(2027, 4, 11);
Period p = Period.between(start, end);
int years = p.getYears(); // 2
int months = p.getMonths(); // 3
int days = p.getDays(); // 10
System.out.println(years + "年" + months + "か月" + days + "日");
JavagetYears() / getMonths() / getDays() で、「何年」「何か月」「何日か」をそれぞれ取り出せます。
ここで重要なのは、
「トータル◯日」というより、「年・月・日それぞれの差」だということです。
1 か月を 30 日と決めつけたりせず、カレンダー通りの差になります。
Period を日付に加える・引く
LocalDate に Period を足したり引いたりできます。
import java.time.LocalDate;
import java.time.Period;
public class PeriodAdd {
public static void main(String[] args) {
LocalDate start = LocalDate.of(2025, 1, 10);
Period period = Period.of(1, 2, 3); // 1年2か月3日
LocalDate result = start.plus(period);
System.out.println(result); // 2026-03-13
}
}
Javaminus(period) とすれば引き算もできます。
Period を使うと、
「1 か月後の締切」
「3 か月ごとの請求日」
「2 年間の契約期間」
といった「カレンダー的な期間」を、そのままコードに表現できます。
Duration:時・分・秒で扱う“ストップウォッチ的な時間”
Duration の基本イメージと生成方法
Duration は「◯時間◯分◯秒◯ナノ秒」という、時間ベースの量を扱います。
対象は LocalTime / LocalDateTime / Instant など、「時刻を含む API」です。
代表的な生成方法はこんな感じです。
import java.time.Duration;
public class DurationBasic {
public static void main(String[] args) {
Duration threeHours = Duration.ofHours(3);
Duration twoMinutes = Duration.ofMinutes(2);
Duration tenSeconds = Duration.ofSeconds(10);
System.out.println(threeHours); // PT3H
System.out.println(twoMinutes); // PT2M
System.out.println(tenSeconds); // PT10S
}
}
JavaofSeconds / ofMinutes / ofHours などで、秒・分・時間ベースの Duration を作れます。
2 つの日時の差から Duration を作る
Duration.between を使うと、2 つの日時の差を「時間量」として求められます。
import java.time.Duration;
import java.time.LocalTime;
public class DurationBetween {
public static void main(String[] args) {
LocalTime start = LocalTime.of(9, 0, 0);
LocalTime end = LocalTime.of(11, 30, 0);
Duration d = Duration.between(start, end);
System.out.println(d); // PT2H30M
System.out.println(d.toHours()); // 2
System.out.println(d.toMinutes()); // 150
System.out.println(d.getSeconds()); // 9000
}
}
Java「9:00 から 11:30 までは、2 時間 30 分(150 分)」という感覚を、そのまま Duration として持てます。
Duration を時刻に加える・引く
import java.time.Duration;
import java.time.LocalDateTime;
public class DurationAdd {
public static void main(String[] args) {
LocalDateTime start = LocalDateTime.of(2025, 1, 10, 9, 0);
Duration d = Duration.ofMinutes(90); // 90分
LocalDateTime result = start.plus(d);
System.out.println(result); // 2025-01-10T10:30
}
}
Java処理時間やタイムアウト時間、待ち時間など、
「純粋な時間量」を足したり引いたりするのに向いています。
Period と Duration の違いを“ちゃんと”整理する
単位の違い(ここが一番大事)
Period
…… 年・月・日ベース。「カレンダー」と同じ単位
Duration
…… 秒・ナノ秒ベース。24 時間= 86400 秒という世界
同じ「1 日」でも、Period と Duration では意味が違うことがあります。
例えば、夏時間(サマータイム)で 1 時間進んだり戻ったりする日を考えます。
import java.time.*;
ZoneId zone = ZoneId.of("Europe/Berlin"); // 夏時間があるタイムゾーン
ZonedDateTime zdt = ZonedDateTime.of(2025, 3, 30, 18, 0, 0, 0, zone);
ZonedDateTime plus1DayWithPeriod = zdt.plus(Period.ofDays(1));
ZonedDateTime plus1DayWithDuration = zdt.plus(Duration.ofDays(1)); // 24時間後
Java公式ドキュメントにもある通り:
- Period.ofDays(1) は「概念上の 1 日」を足すので、翌日の 18:00 になります
- Duration.ofDays(1) は「正確に 24 時間」を足すので、夏時間ギャップがある場合は 翌日の 19:00 になることがあります
つまり、
「カレンダー上で 1 日後」なら Period
「24 時間後きっちり」なら Duration
と使い分けが必要です。
何と一緒に使うかの違い
Period は LocalDate(日付だけ)との相性が良く、Duration は LocalTime / LocalDateTime / Instant など「時刻を含む型」との相性が良いです。
ざっくり言うと、
日付の差・日付ベースの期間 → Period
時間・処理時間・待ち時間 → Duration
という棲み分けを意識しておくと、かなり整理されます。
実務でありがちな例でイメージを固める
例1:2 つの日付の「年・月・日」の差を出したい(Period)
「入社日から今日までで、何年何か月働いたか?」
これは Period の出番です。
import java.time.LocalDate;
import java.time.Period;
public class WorkPeriod {
public static void main(String[] args) {
LocalDate joined = LocalDate.of(2020, 4, 1);
LocalDate today = LocalDate.now();
Period period = Period.between(joined, today);
int years = period.getYears();
int months = period.getMonths();
int days = period.getDays();
System.out.println("勤続 " + years + "年" + months + "か月" + days + "日");
}
}
Java「何日間働いたか(トータル日数)」というより、
「何年・何か月・何日」という“人間向けの表現”に向いています。
例2:処理時間を測りたい(Duration)
処理時間・レスポンスタイムなどの計測には、Duration がぴったりです。
import java.time.Duration;
import java.time.Instant;
public class MeasureTime {
public static void main(String[] args) {
Instant start = Instant.now();
// 何か重い処理
doHeavyWork();
Instant end = Instant.now();
Duration d = Duration.between(start, end);
System.out.println("処理時間(ミリ秒): " + d.toMillis());
System.out.println("処理時間(秒): " + d.toMillis() / 1000.0);
}
private static void doHeavyWork() {
try {
Thread.sleep(1234); // ダミーで1.234秒スリープ
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}
JavatoMillis() / toSeconds() などで単位を変換できるので、
ストップウォッチのように扱えます。
Period と Duration をどのように頭に定着させるか
Period と Duration を、初心者向けに整理するとこうなります。
- Period
…… 年・月・日ベースの期間。カレンダー的な「◯年◯か月◯日」。
……LocalDateの差や、「1 か月後の締切」「2 年間の契約」などに使う。 - Duration
…… 秒・ナノ秒ベースの時間量。ストップウォッチ的な「◯時間◯分◯秒」。
…… 処理時間、タイムアウト、待ち時間、「きっちり 24 時間後」などに使う。
特に意識してほしいポイントは、
「カレンダー上の期間を扱いたいのか」
「時間量(秒・分・時間)を扱いたいのか」
この質問を自分にしてみて、前者なら Period、後者なら Duration を選ぶ、という感覚です。
