Есть ли простой способ узнать количество лет и дней между двумя датами? - PullRequest
0 голосов
/ 20 сентября 2019

У меня есть строка, представляющая дату рождения. Я хочу знать, сколько лет человеку в годах и днях.

Например: рождение = 07/04/1994 (месяц / дни / годы)

Таким образом, этому человеку 25–78 лет

Но пока, используя datetime, когда я делаю вычитание между датами, результат получается как число дней.И из-за високосных лет я никогда не могу быть уверен в точном количестве дней.


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

Ответы [ 3 ]

1 голос
/ 20 сентября 2019

Не так просто, как встроенная функция Python , но, безусловно, выполнимо с использованием следующей логики:

  1. Построить дату на основе текущего года минус один, но день рождения месяц и день.Назовите это lastYearBirthday.Также постройте дату на основе текущего года, но месяца и дня рождения.Назовите это currYearBirthday.

  2. Если currYearBirthday после today (день рождения еще не наступил в этом году), число полных лет можно получить, вычтя year(birthdate) с year(lastYearBirthday).Количество дней сверх (дней с последнего дня рождения), полученное с помощью (today - lastYearBirthday).days.

  3. В противном случае этот день рождения уже наступил (или происходит сегодня), и числополные годы могут быть получены путем вычитания year(birthdate) из year(currYearBirthday) - количества дней сверх того, которое получается с (today - currYearBirthday).days.

Превратив это в функцию Python, вы можете использоватьлегко, мы получаем:

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)

И некоторый тестовый код показывает мое собственное опасное положение на этой смертной катушке:

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

Выходное значение (в деньэтот ответ был опубликован) довольно удручающе:

54 years and 230 days

: -)

Обратите внимание, что я только что построил свою дату рождения непосредственно из года, месяца и дня.Поскольку вы уже знаете, как превратить строку в одну из них (согласно вашему вопросу), я не стал использовать этот метод.

0 голосов
/ 20 сентября 2019

Много упражнений из старых добрых времен по переполнению стека в сентябре.Это должно проиллюстрировать вам логику.Обратите внимание, что год является високосным только тогда, когда он идеально разделен на 4, 100 или 400. Затем вы можете использовать атрибуты datetime, чтобы повеселиться.

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

days = delta.days
year_counter = 0
if today.day >= birth_date.day and today.month >= birth_date.month:
    full_years = today.year
else:
    full_years = today.year - 1

for year in range(1996, full_years):
    if (year % 4) == 0 or (year % 100) == 0 or (year % 400) == 0:
        days -= 366
        year_counter += 1
    else:
        days -= 365
        year_counter += 1

print("years: " + str(year_counter) + "\ndays: " + str(days))

Очевидно, что есть и более Pythonic способ написать это, ноЯ полагаю, вы хотели немного читабельности.

0 голосов
/ 20 сентября 2019

Пользователь создал этот следующий код для другого ответа в стеке, который отражает логику високосного года.С учетом сказанного вам потребуется рефакторинг в соответствии с вашими потребностями ...

#Calculate the Days between Two Date

daysOfMonths = [ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]

def isLeapYear(year):

    # Pseudo code for this algorithm is found at
    # http://en.wikipedia.org/wiki/Leap_year#Algorithm
    ## if (year is not divisible by 4) then (it is a common Year)
    #else if (year is not divisable by 100) then (ut us a leap year)
    #else if (year is not disible by 400) then (it is a common year)
    #else(it is aleap year)
    return (year % 4 == 0 and year % 100 != 0) or year % 400 == 0

def Count_Days(year1, month1, day1):
    if month1 ==2:
        if isLeapYear(year1):
            if day1 < daysOfMonths[month1-1]+1:
                return year1, month1, day1+1
            else:
                if month1 ==12:
                    return year1+1,1,1
                else:
                    return year1, month1 +1 , 1
        else: 
            if day1 < daysOfMonths[month1-1]:
                return year1, month1, day1+1
            else:
                if month1 ==12:
                    return year1+1,1,1
                else:
                    return year1, month1 +1 , 1
    else:
        if day1 < daysOfMonths[month1-1]:
             return year1, month1, day1+1
        else:
            if month1 ==12:
                return year1+1,1,1
            else:
                    return year1, month1 +1 , 1


def daysBetweenDates(y1, m1, d1, y2, m2, d2,end_day):

    if y1 > y2:
        m1,m2 = m2,m1
        y1,y2 = y2,y1
        d1,d2 = d2,d1
    days=0
    while(not(m1==m2 and y1==y2 and d1==d2)):
        y1,m1,d1 = Count_Days(y1,m1,d1)
        days+=1
    if end_day:
        days+=1
    return days


# Test Case

def test():
    test_cases = [((2012,1,1,2012,2,28,False), 58), 
                  ((2012,1,1,2012,3,1,False), 60),
                  ((2011,6,30,2012,6,30,False), 366),
                  ((2011,1,1,2012,8,8,False), 585 ),
                  ((1994,5,15,2019,8,31,False), 9239),
                  ((1999,3,24,2018,2,4,False), 6892),
                  ((1999,6,24,2018,8,4,False),6981),
                  ((1995,5,24,2018,12,15,False),8606),
                  ((1994,8,24,2019,12,15,True),9245),
                  ((2019,12,15,1994,8,24,True),9245),
                  ((2019,5,15,1994,10,24,True),8970),
                  ((1994,11,24,2019,8,15,True),9031)]

    for (args, answer) in test_cases:
        result = daysBetweenDates(*args)
        if result != answer:
            print "Test with data:", args, "failed"
        else:
            print "Test case passed!"

test()

Как рассчитать количество дней между двумя указанными датами?

...