Search code examples
pythonpython-datetime

Is there a simple way to get the number of years and days between 2 dates?


I have a string representing a birth date I want to know how old the person is in years and days.

e.g: birth = 07/04/1994 (month/days/years)

So the person is 25y 78d old

But so far, using datetime when I do substraction between dates the result it as number of days. And because of leap years I can never be sure of the exact number of days.


In [1]:
from datetime import date, datetime
today = date.today()

birth = '10/21/1996'
birth_date = datetime.strptime(datetime.strptime(birth, '%m/%d/%Y').strftime('%Y-%m-%d'),'%Y-%m-%d').date()
delta = today - birth_date
print(delta.days)

Out [1]:
8369

Solution

  • Not as simple as a built-in Python function, but certainly doable using the following logic:

    1. Construct a date based on the current year minus one, but the birth month and day. Call this lastYearBirthday. Also construct a date based on the current year but the birth month and day. Call this currYearBirthday.

    2. If currYearBirthday is after today (the birthday is yet to occur this year), the number of full years can be obtained by subtracting year(birthdate) from year(lastYearBirthday). The number of days over and above (days since last birthday) that is obtained with (today - lastYearBirthday).days.

    3. Otherwise this years birthday has already happened (or is happening today) and the number of full years can therefore be obtained by subtracting year(birthdate) from year(currYearBirthday) - the number of days over that is obtained with (today - currYearBirthday).days.

    Turning that into a Python function you can use easily, we get:

    from datetime import date
    
    # Functions to return tuple of (fullYears, extraDays) for
    # a given birth date.
    
    def ageInYearsAndDays(birthDate):
        # Create relevant dates to ease task.
    
        today = date.today()
        lastYearBirthday = date(today.year - 1, birthDate.month, birthDate.day)
        currYearBirthday = date(today.year, birthDate.month, birthDate.day)
    
        # Work out years and days based on whether this years
        # birthday has happened. Basic idea is that years can
        # be calculated as difference between birth year and
        # year of most recent birthday. Days is the number of
        # days between most recent birthday and today.
    
        if currYearBirthday > today:
            years = lastYearBirthday.year - birthDate.year
            days = (today - lastYearBirthday).days
        else:
            years = currYearBirthday.year - birthDate.year
            days = (today - currYearBirthday).days
    
        return (years, days)
    

    And some test code shows my own precarious position on this mortal coil:

    (years, days) = ageInYearsAndDays(date(1965, 2, 2))
    print(years, "years and", days, "days")
    

    The output being (on the day this answer was posted) a rather depressing:

    54 years and 230 days
    

    :-)

    Note that I just constructed my birthdate from year, month and day directly. Since you already know how to turn a string into one of those (as per your question), I didn't bother using that method.