有没有一种简单的方法可以获取两个日期之间的年数和天数?

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

我有一个表示出生日期的字符串我想知道这个人的年龄和天数。

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

So the person is 25y 78d old

但到目前为止,当我在日期之间进行减法时使用 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

不像内置 Python函数那么简单,但使用以下逻辑肯定可行:

  1. 根据当前年份减一构造一个日期,但出生月份和日期。称之为 lastYearBirthday。还根据当前年份但出生月份和日期构建日期。调用此 currYearBirthday.

  2. 如果currYearBirthdaytoday之后(今年还未过生日),则用year(birthdate)减去year(birthdate)即可得到整年数year(lastYearBirthday)。用 (today - lastYearBirthday).days.

  3. 得到的超过天数(自上次生日以来的天数)
  4. 否则今年的生日已经过了(或今天正在过),因此可以通过 year(currYearBirthday) 减去 year(birthdate) 得到整年的数目 -通过 (today - currYearBirthday).days.

  5. 获得的天数

将其转换为您可以轻松使用的 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

:-)

请注意,我只是直接根据年月日构造我的生日。由于您已经知道如何将字符串转换为其中的一种(根据您的问题),所以我没有费心使用该方法。

用户为捕获闰年逻辑的堆栈上的另一个答案构建了以下代码。话虽如此,您将需要重构以满足您的需求...

#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()

How to calculate number of days between two given dates?

9 月份大量关于堆栈的好日子的练习。这应该向您说明逻辑。请注意,只有在完全除以 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 的方式来编写它,但我想你想要一些可读性。