はじめに
簡単に実装しようとするとこんな感じになると思います。
val age = (today.year - birthDate.year)
これだと誕生日をまだ迎えていない場合に1歳ずれます。
Period.between を使う
val age = Period.between(birthDate, LocalDate.now()).years
たったこれだけで、うるう年・月末生まれ・誕生日当日の扱いがすべて正しく計算されます。
today.year - birthDate.yearだとなぜ自前計算は危ないか
// 3月31日生まれの人が4月1日時点で何歳か
val birth = LocalDate.of(1990, 3, 31)
val today = LocalDate.of(2026, 4, 1)
// 単純な年差
today.year - birth.year // → 36
// Period
Period.between(birth, today).years // → 35
使い方
最大心拍数の推定など、年齢を使う計算と組み合わせるとこうなります。
fun ageFromBirthDate(birthDate: LocalDate): Int =
Period.between(birthDate, LocalDate.now()).years.coerceAtLeast(0)
fun estimateMaxHeartRate(age: Int): Int = (208 - 0.7 * age).toInt()
coerceAtLeast(0) を使えば、未来の誕生日(負の年齢)も安全に処理できます。
まとめ
- 年齢計算は Period.between(birthDate, today).years の1行で正確に出る
- うるう年・月末・誕生日当日はすべて自動で正しく処理される
- 負の値が返る可能性がある場合は coerceAtLeast(0) で安全に