日期计算之间的天数

时间:2014-03-15 04:23:19

标签: python date calendar date-arithmetic

我正在创建一个函数包,它们从日期中获取不同的值,如下面的代码所示。它有效,但它有时会返回少量关闭的值。

代码:

    #CALENDAR TOOLS FUNCTIONS
    #CALENDAR INDEXING USES FORMAT: MMM DD, YYYY

    #example: "Aug 17, 1998"

    month = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']                
    monthLength = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]

    def getMonth(date):
        return date[0:3]

    def getDay(date):
        return int(date[4:6])

    def getYear(date):
        return int(date[8:12])

    def years(a, b):
        a = getYear(a)
        b = getYear(b)
        if a > b:
            return a - b - 1
        else:
            return b - a - 1

    def days(a, b):

        #switches years if start date is past end date
        if (getYear(a) > getYear(b) or
            getYear(a) == getYear(b) and month.index(getMonth(a)) >         month.index(getMonth(b)) or
            getYear(a) == getYear(b) and month.index(getMonth(a)) == month.index(getMonth(b)) and getDay(a) > getDay(b)):
            a, b = b, a

        dayA = getDay(a)
        monthA = getMonth(a)
        yearA = getYear(a)

        dayB = getDay(b)
        monthB = getMonth(b)
        yearB = getYear(b)

        remDays = monthLength[month.index(monthA)] - dayA + 1
        for i in range(month.index(monthA), 11):
            remDays += monthLength[i]

        prevDays = dayB
        for i in range(0, month.index(monthB)):
            prevDays += monthLength[i]

        yearDays = round(years(a, b) * 365.24218967, 0)
        totalDays = yearDays + remDays + prevDays
        return totalDays

当我使用具有某些日期的日期函数时,它会对某些日期有所影响,但对其他日期有所不同,如果我输入,我会给出一个示例:

days("Jan 01, 2013", "Dec 31, 2015")

我得到了1095天的正确答案 如果http://www.timeanddate.com/date/duration.html

是正确的,我会得到

但是当我输入时:

days("Jan 01, 1908", "Sep 07, 2000")

这一天我得到了33852天 从timeanddate.com网站上我得到33,791巨大的差异,我不明白为什么

2 个答案:

答案 0 :(得分:2)

你对闰年的处理被打破了。闰年有确切的规则,如果你使用逻辑(years(a, b) * 365.24218967)来近似它们,你会得到错误的结果。

将您的输入转换为datetime.date()对象并使用其差异。

def days_diff(a, b):
    dta = datetime.date(getYear(a), getMonth(a), getDay(a))
    dtb = datetime.date(getYear(b), getMonth(b), getDay(b))
    return (dta - dtb).days

编辑:阅读您的评论,以表达您的乐趣并且不想使用Python的内置时间功能。然后,正如Jayanth所评论的那样,要适当照顾闰年。在规则发生时查看并实施规则。

答案 1 :(得分:1)

如果你是为了好玩的话,我不会改变你所做的事情。你所遗漏的(正如一些人指出的那样)是闰年计算。还有几个细节:

1)第一个prevDays循环应该从month.index(monthA)+ 1到12.记住,range()包括第一个arg但不包括第二个arg,如:[arg1,arg2]。

2)你有一个额外的+ 1的remDays。它不应该存在。

3)您错过了闰年计算。您可以将闰年计算为

def is_leap_year(year):
    return (year % 4 == 0 and year % 100 != 0) or year % 400 == 0

所以,在你的月份循环中,我添加:

for i in range(month.index(monthA) + 1, 12):
    remDays += monthLength[i] + (1 if i == 1 and is_leap_year(yearA) else 0)

for i in range(0, month.index(monthB)):
    prevDays += monthLength[i] + (1 if i == 1 and is_leap_year(yearB) else 0)

最后,您需要在闰年而不是365上添加366天。因此,继续您的循环风格,这将是年度计算:

yearDays = 0
for year in range(yearA + 1, yearB):
    yearDays += 366 if is_leap_year(year) else 365

请注意,这最后一块将代替你的圆形(..)。