我正在创建一个函数包,它们从日期中获取不同的值,如下面的代码所示。它有效,但它有时会返回少量关闭的值。
代码:
#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巨大的差异,我不明白为什么
答案 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
请注意,这最后一块将代替你的圆形(..)。