Java ChronoUnit クラス

ChronoUnit は Java 8 で導入された列挙型クラスで、java.time.temporalパッケージに属します。

ChronoUnit は、日付と時刻の異なる粒度を表すための標準的な時間単位のセットを定義しています。ChronoUnit は主に Java 8 の日時 API(例:LocalDate、LocalTime、LocalDateTimeなど)と一緒に使用され、時間の計算と比較を行います。


コア機能

1. 時間単位の表現

ChronoUnit は、ナノ秒から世紀までのさまざまな時間単位を提供しています:

  • NANOS:ナノ秒
  • MICROS:マイクロ秒
  • MILLIS:ミリ秒
  • SECONDS:秒
  • MINUTES:分
  • HOURS:時
  • HALF_DAYS:半日(12時間)
  • DAYS:日
  • WEEKS:週
  • MONTHS:月
  • YEARS:年
  • DECADES:10年
  • CENTURIES:世紀
  • MILLENNIA:千年
  • ERAS:紀元

2. 時間計算

ChronoUnit は、Temporalオブジェクト(例:LocalDate)と一緒に使用して、時間の加減算操作を行うことができます。

例

LocalDate today = LocalDate.now();
LocalDate nextWeek = today.plus(1, ChronoUnit.WEEKS); // 1週間を加算
LocalDate lastMonth = today.minus(1, ChronoUnit.MONTHS); // 1か月を減算

3. 時間差の計算

次のメソッドを使用して、between()2つの時点の差を計算できます。

例

LocalDate start = LocalDate.of(2023, 1, 1);
LocalDate end = LocalDate.of(2023, 12, 31);
long days = ChronoUnit.DAYS.between(start, end); // 日数の差を計算

よく使われるメソッドの詳細解説

1. between() メソッド

2つの Temporal オブジェクト間の時間差を計算します。

例

public long between(Temporal temporal1Inclusive, Temporal temporal2Exclusive)

例:

例

LocalDateTime start = LocalDateTime.of(2023, 1, 1, 0, 0);
LocalDateTime end = LocalDateTime.of(2023, 1, 2, 12, 0);
long hours = ChronoUnit.HOURS.between(start, end); // 36時間

2. addTo() メソッド

時間単位を Temporal オブジェクトに追加します。

例

public Temporal addTo(Temporal temporal, long amount)

例:

例

LocalTime time = LocalTime.of(14, 30);
LocalTime newTime = (LocalTime) ChronoUnit.HOURS.addTo(time, 3); // 17:30

3. isSupportedBy() メソッド

Temporal オブジェクトがその時間単位をサポートしているかどうかを確認します。

例

public boolean isSupportedBy(Temporal temporal)

例:

例

LocalDate date = LocalDate.now();
boolean supported = ChronoUnit.HOURS.isSupportedBy(date); // false。LocalDate は時間単位をサポートしていないため

実際の応用例

1. 年齢の計算

例

LocalDate birthDate = LocalDate.of(1990, 5, 15);
LocalDate now = LocalDate.now();
long age = ChronoUnit.YEARS.between(birthDate, now);
System.out.println("年齢: " + age + " 歳");

2. プロジェクトの期間計算

例

LocalDateTime projectStart = LocalDateTime.of(2023, 1, 1, 9, 0);
LocalDateTime projectEnd = LocalDateTime.of(2023, 6, 30, 18, 0);
long months = ChronoUnit.MONTHS.between(projectStart, projectEnd);
long days = ChronoUnit.DAYS.between(projectStart, projectEnd);
System.out.println("プロジェクト期間: " + months + " か月、または " + days + " 日");

3. 日付シーケンスの生成

例

LocalDate start = LocalDate.of(2023, 1, 1);
List<LocalDate> dates = new ArrayList<>();
for (int i = 0; i < 7; i++) {
    dates.add(start.plus(i, ChronoUnit.DAYS));
}

簡単な例

例

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;

public class ChronoUnitExample {
    public static void main(String[] args) {
        // 1. 2つの日付の間の日数を計算
        LocalDate today = LocalDate.now();
        LocalDate nextWeek = today.plus(1, ChronoUnit.WEEKS);
        long daysBetween = ChronoUnit.DAYS.between(today, nextWeek);
        System.out.println("今日から来週の今日までの日数: " + daysBetween);
       
        // 2. 時間の加算・減算
        LocalDateTime now = LocalDateTime.now();
        System.out.println("現在時刻: " + now);
       
        LocalDateTime in2Hours = now.plus(2, ChronoUnit.HOURS);
        System.out.println("2時間後: " + in2Hours);
       
        LocalDateTime yesterday = now.minus(1, ChronoUnit.DAYS);
        System.out.println("昨日のこの時刻: " + yesterday);
       
        // 3. 2つの時点の間の時間数を計算
        long hoursBetween = ChronoUnit.HOURS.between(yesterday, now);
        System.out.println("昨日のこの時刻から現在までの時間数: " + hoursBetween);
       
        // 4. 異なる時間単位を使用
        System.out.println("分の差: " + ChronoUnit.MINUTES.between(yesterday, now));
        System.out.println("秒の差: " + ChronoUnit.SECONDS.between(yesterday, now));
       
        // 5. 時間単位が特定の型をサポートしているか確認
        System.out.println("DAYSがLocalDateをサポートしているか: " + ChronoUnit.DAYS.isSupportedBy(today));
        System.out.println("HOURSがLocalDateをサポートしているか: " + ChronoUnit.HOURS.isSupportedBy(today));
    }
}

出力結果は次のとおりです:

今天和下周今天之间的天数: 7
当前时间: 2025-05-01T11:22:22.247669
两小时后: 2025-05-01T13:22:22.247669
昨天此时: 2025-04-30T11:22:22.247669
昨天此时到现在的小时数: 24
相差的分钟数: 1440
相差的秒数: 86400
DAYS是否支持LocalDate: true
HOURS是否支持LocalDate: false

年齢の計算

例

import java.time.LocalDate;
import java.time.temporal.ChronoUnit;

public class AgeCalculator {
    public static void main(String[] args) {
        LocalDate birthDate = LocalDate.of(1990, 5, 15);
        LocalDate currentDate = LocalDate.now();
       
        long years = ChronoUnit.YEARS.between(birthDate, currentDate);
        long months = ChronoUnit.MONTHS.between(birthDate, currentDate) % 12;
        long days = ChronoUnit.DAYS.between(
            birthDate.plusYears(years).plusMonths(months),
            currentDate
        );
       
        System.out.printf("年齢: %d 年 %d か月 %d 日%n", years, months, days);
    }
}

出力結果は次のとおりです:

年龄: 34 年 11 个月 16 天

注意事項

  1. 時間単位のサポート:すべての Temporal オブジェクトがすべての ChronoUnit をサポートしているわけではありません。例えば、LocalDateはサポートされていません。HOURS 或 MINUTES。

  2. 負の値の処理:最初のパラメータが2番目のパラメータより後の場合、between()メソッドは負の値を返します。

  3. 精度の問題:大きな時間単位(MONTHS や YEARS など)の場合、これらの単位の日数が固定されていないため、計算は完全に正確ではない可能性があります。

  4. パフォーマンスの考慮事項:頻繁な時間計算には、ChronoUnit を使用する方が手動計算よりも効率的で、エラーが発生しにくくなります。


他のクラスとの比較

1. ChronoUnit vs TimeUnit

  • TimeUnit主にスレッドのスリープと並行操作に使用され、時間単位の粒度が細かい(ナノ秒から日まで)
  • ChronoUnit日時 API 専用に設計されており、より大きな時間単位(週から千年まで)をサポートします

2. ChronoUnit vs Duration/Period

  • Duration正確な時間量(ナノ秒から日まで)に使用されます
  • Period日付の量(日から年まで)に使用されます
  • ChronoUnitより柔軟な単位選択と計算方法を提供します
その他の拡張