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 nextWeek = today.plus(1, ChronoUnit.WEEKS); // 1週間を加算
LocalDate lastMonth = today.minus(1, ChronoUnit.MONTHS); // 1か月を減算
3. 時間差の計算
次のメソッドを使用して、between()2つの時点の差を計算できます。
例
LocalDate end = LocalDate.of(2023, 12, 31);
long days = ChronoUnit.DAYS.between(start, end); // 日数の差を計算
よく使われるメソッドの詳細解説
1. between() メソッド
2つの Temporal オブジェクト間の時間差を計算します。
例
例:
例
LocalDateTime end = LocalDateTime.of(2023, 1, 2, 12, 0);
long hours = ChronoUnit.HOURS.between(start, end); // 36時間
2. addTo() メソッド
時間単位を Temporal オブジェクトに追加します。
例
例:
例
LocalTime newTime = (LocalTime) ChronoUnit.HOURS.addTo(time, 3); // 17:30
3. isSupportedBy() メソッド
Temporal オブジェクトがその時間単位をサポートしているかどうかを確認します。
例
例:
例
boolean supported = ChronoUnit.HOURS.isSupportedBy(date); // false。LocalDate は時間単位をサポートしていないため
実際の応用例
1. 年齢の計算
例
LocalDate now = LocalDate.now();
long age = ChronoUnit.YEARS.between(birthDate, now);
System.out.println("年齢: " + age + " 歳");
2. プロジェクトの期間計算
例
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. 日付シーケンスの生成
例
List<LocalDate> dates = new ArrayList<>();
for (int i = 0; i < 7; i++) {
dates.add(start.plus(i, ChronoUnit.DAYS));
}
簡単な例
例
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.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 天
注意事項
時間単位のサポート:すべての Temporal オブジェクトがすべての ChronoUnit をサポートしているわけではありません。例えば、
LocalDateはサポートされていません。HOURS或MINUTES。負の値の処理:最初のパラメータが2番目のパラメータより後の場合、
between()メソッドは負の値を返します。精度の問題:大きな時間単位(MONTHS や YEARS など)の場合、これらの単位の日数が固定されていないため、計算は完全に正確ではない可能性があります。
パフォーマンスの考慮事項:頻繁な時間計算には、ChronoUnit を使用する方が手動計算よりも効率的で、エラーが発生しにくくなります。
他のクラスとの比較
1. ChronoUnit vs TimeUnit
TimeUnit主にスレッドのスリープと並行操作に使用され、時間単位の粒度が細かい(ナノ秒から日まで)ChronoUnit日時 API 専用に設計されており、より大きな時間単位(週から千年まで)をサポートします
2. ChronoUnit vs Duration/Period
Duration正確な時間量(ナノ秒から日まで)に使用されますPeriod日付の量(日から年まで)に使用されますChronoUnitより柔軟な単位選択と計算方法を提供します