Python で2つの日時の差から年齢や経過年数を計算する

生年月日から年齢を計算したり、入社日から勤続年数を求めたりする場面は多いです。Python で2つの日付の差から「年数」を正確に計算する方法を解説します。

単純な年の差は不正確

まず、やりがちな間違いを見てみましょう。

from datetime import date

birth = date(1990, 12, 25)
today = date(2025, 1, 15)

# これは不正確
age = today.year - birth.year
print(age)  # 35

この計算だと、誕生日がまだ来ていない場合でも年齢が1歳多くなってしまいます。2025年1月15日時点では、12月25日生まれの人はまだ34歳のはずです。

正確な年齢計算

誕生日が今年すでに過ぎたかどうかを考慮する必要があります。

from datetime import date

def calculate_age(birth_date, today=None):
    if today is None:
        today = date.today()
    
    age = today.year - birth_date.year
    
    # 今年の誕生日がまだ来ていなければ 1 を引く
    if (today.month, today.day) < (birth_date.month, birth_date.day):
        age -= 1
    
    return age

birth = date(1990, 12, 25)
print(calculate_age(birth, date(2025, 1, 15)))   # 34
print(calculate_age(birth, date(2025, 12, 25)))  # 35
print(calculate_age(birth, date(2025, 12, 26)))  # 35

タプルの比較を使って、月日がまだ来ていないかをチェックしています。

dateutil の relativedelta を使う

dateutil ライブラリの relativedelta を使うと、より直感的に年数・月数・日数を取得できます。

from datetime import date
from dateutil.relativedelta import relativedelta

birth = date(1990, 12, 25)
today = date(2025, 1, 15)

delta = relativedelta(today, birth)
print(f"{delta.years}{delta.months}ヶ月 {delta.days}")
# 34歳 0ヶ月 21日

relativedelta は年・月・日を別々の属性として持っているため、細かい経過期間を表示したい場合に便利です。

勤続年数を計算する

入社日からの勤続年数も同じ考え方で計算できます。

from datetime import date
from dateutil.relativedelta import relativedelta

join_date = date(2018, 4, 1)
today = date(2025, 1, 15)

delta = relativedelta(today, join_date)
print(f"勤続 {delta.years}{delta.months}ヶ月")
# 勤続 6年 9ヶ月

人事システムや社内ツールでよく使われるパターンですね。

timedelta では年数は取れない

標準ライブラリの timedelta は日数しか保持しないため、単純に365で割っても正確な年数になりません。

from datetime import date

birth = date(1990, 12, 25)
today = date(2025, 1, 15)

delta = today - birth
print(delta.days)  # 12440

# これは不正確(うるう年を考慮していない)
rough_years = delta.days / 365
print(rough_years)  # 34.08...

おおよその値は得られますが、正確な年齢計算には使えません。

満年齢と数え年

日本では「数え年」という数え方もありますが、法律上の年齢は「満年齢」で計算します。

満年齢

生まれた日を0歳とし、誕生日ごとに1歳加算する

数え年

生まれた年を1歳とし、元日ごとに1歳加算する

この記事で紹介した方法は満年齢の計算です。数え年が必要な場合は、別のロジックを組む必要があります。

from datetime import date

def calculate_kazoedoshi(birth_date, today=None):
    """数え年を計算する"""
    if today is None:
        today = date.today()
    return today.year - birth_date.year + 1

birth = date(1990, 12, 25)
print(calculate_kazoedoshi(birth, date(2025, 1, 15)))  # 36

用途に応じて適切な計算方法を選んでください。