如何计算两个给定日期之间的天数

如果我有两个日期(例如'8/18/2008''9/26/2008'),获得这两个日期之间天数的最佳方法是什么?

915559 次浏览

如果您有两个date对象,您可以将它们相减,这将计算一个timedelta对象。

from datetime import date


d0 = date(2008, 8, 18)
d1 = date(2008, 9, 26)
delta = d1 - d0
print(delta.days)

文档的相关部分: https://docs.python.org/library/datetime.html.

另一个例子见这个答案

使用datetime的力量:

from datetime import datetime
date_format = "%m/%d/%Y"
a = datetime.strptime('8/18/2008', date_format)
b = datetime.strptime('9/26/2008', date_format)
delta = b - a
print delta.days # that's it

圣诞节前几天:

>>> import datetime
>>> today = datetime.date.today()
>>> someday = datetime.date(2008, 12, 25)
>>> diff = someday - today
>>> diff.days
86

更多算术这里

您需要datetime模块。

>>> from datetime import datetime, timedelta
>>> datetime(2008,08,18) - datetime(2008,09,26)
datetime.timedelta(4)

另一个例子:

>>> import datetime
>>> today = datetime.date.today()
>>> print(today)
2008-09-01
>>> last_year = datetime.date(2007, 9, 1)
>>> print(today - last_year)
366 days, 0:00:00

正如所指出的这里

from datetime import datetime
start_date = datetime.strptime('8/18/2008', "%m/%d/%Y")
end_date = datetime.strptime('9/26/2008', "%m/%d/%Y")
print abs((end_date-start_date).days)

from datetime import date
def d(s):
[month, day, year] = map(int, s.split('/'))
return date(year, month, day)
def days(start, end):
return (d(end) - d(start)).days
print days('8/18/2008', '9/26/2008')

当然,这假设您已经验证了日期的格式为r'\d+/\d+/\d+'

它也可以通过arrow轻松完成:

import arrow


a = arrow.get('2017-05-09')
b = arrow.get('2017-05-11')


delta = (b-a)
print delta.days

参考:http://arrow.readthedocs.io/en/latest/

对于计算日期和时间,有几个选项,但我会写简单的方法:

from datetime import timedelta, datetime, date
import dateutil.relativedelta


# current time
date_and_time = datetime.now()
date_only = date.today()
time_only = datetime.now().time()


# calculate date and time
result = date_and_time - timedelta(hours=26, minutes=25, seconds=10)


# calculate dates: years (-/+)
result = date_only - dateutil.relativedelta.relativedelta(years=10)


# months
result = date_only - dateutil.relativedelta.relativedelta(months=10)


# days
result = date_only - dateutil.relativedelta.relativedelta(days=10)


# calculate time
result = date_and_time - timedelta(hours=26, minutes=25, seconds=10)
result.time()

希望有帮助

不使用Lib只是纯代码:

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

这里有三种方法来解决这个问题:

from datetime import datetime


Now = datetime.now()
StartDate = datetime.strptime(str(Now.year) +'-01-01', '%Y-%m-%d')
NumberOfDays = (Now - StartDate)


print(NumberOfDays.days)                     # Starts at 0
print(datetime.now().timetuple().tm_yday)    # Starts at 1
print(Now.strftime('%j'))                    # Starts at 1

还有一个datetime.toordinal()方法还没有提到:

import datetime
print(datetime.date(2008,9,26).toordinal() - datetime.date(2008,8,18).toordinal())  # 39

https://docs.python.org/3/library/datetime.html#datetime.date.toordinal

date.序数

返回日期的公历序数,其中1年1月1日的序数为1。对于任何date对象ddate.fromordinal(d.toordinal()) == d.

似乎很适合计算天差,虽然不像timedelta.days那样易读。

每个人都很好地回答了日期, 让我试着用熊猫来回答它

dt = pd.to_datetime('2008/08/18', format='%Y/%m/%d')
dt1 = pd.to_datetime('2008/09/26', format='%Y/%m/%d')


(dt1-dt).days

这就是答案。 如果其中一个输入是数据帧列。只需使用dt.days代替

(dt1-dt).dt.days

在python中不使用datetime对象。

# A date has day 'd', month 'm' and year 'y'
class Date:
def __init__(self, d, m, y):
self.d = d
self.m = m
self.y = y


# To store number of days in all months from
# January to Dec.
monthDays = [31, 28, 31, 30, 31, 30,
31, 31, 30, 31, 30, 31 ]


# This function counts number of leap years
# before the given date
def countLeapYears(d):


years = d.y


# Check if the current year needs to be considered
# for the count of leap years or not
if (d.m <= 2) :
years-= 1


# An year is a leap year if it is a multiple of 4,
# multiple of 400 and not a multiple of 100.
return int(years / 4 - years / 100 + years / 400 )




# This function returns number of days between two
# given dates
def getDifference(dt1, dt2) :


# COUNT TOTAL NUMBER OF DAYS BEFORE FIRST DATE 'dt1'


# initialize count using years and day
n1 = dt1.y * 365 + dt1.d


# Add days for months in given date
for i in range(0, dt1.m - 1) :
n1 += monthDays[i]


# Since every leap year is of 366 days,
# Add a day for every leap year
n1 += countLeapYears(dt1)


# SIMILARLY, COUNT TOTAL NUMBER OF DAYS BEFORE 'dt2'


n2 = dt2.y * 365 + dt2.d
for i in range(0, dt2.m - 1) :
n2 += monthDays[i]
n2 += countLeapYears(dt2)


# return difference between two counts
return (n2 - n1)




# Driver program
dt1 = Date(31, 12, 2018 )
dt2 = Date(1, 1, 2019 )


print(getDifference(dt1, dt2), "days")

如果你想自己编码计算,那么这里有一个函数,它将返回给定年、月和日的序数:

def ordinal(year, month, day):
return ((year-1)*365 + (year-1)//4 - (year-1)//100 + (year-1)//400
+ [ 0,31,59,90,120,151,181,212,243,273,304,334][month - 1]
+ day
+ int(((year%4==0 and year%100!=0) or year%400==0) and month > 2))

此函数与datetime模块中的date.toordinal方法兼容。

您可以获得两个日期之间的差异天数,如下所示:

print(ordinal(2021, 5, 10) - ordinal(2001, 9, 11))

如果你没有一个日期处理库(或者你怀疑它有错误),这里有一个抽象算法,应该很容易翻译成大多数语言。

在每个日期执行以下计算,然后简单地减去两个结果。所有商和余数都是正整数。

步骤A.首先将日期的部分标识为Y(年)、M(月)和D(日)。这些是随着我们的进行而变化的变量。

步骤B.从M中减去3

(所以1月是-2,12月是9)。

步骤C.如果M为负数,则将M加上12并从年份Y中减去1。

(这将“一年的开始”更改为3月1日,月份编号为0(3月)到11(2月)。这样做的原因是“一年中的天数”在Spring年和普通年之间不会改变,所以“短”月是在年底,所以下一个月不需要特殊处理。)

步骤D. 将M除以5得到商Q和余数R。将Q×153添加到D。在下一步中使用R。

(从3月1日开始,每5个月有153天。

步骤E.将R除以2以获得商Q 2并忽略余数。将R×31-Q 2添加到D。

(在每组5个月中,每2个月有61天,其中每对月的第一个月是31天。可以忽略2月短于30天的事实,因为此时您只关心2月1日的天数,而不是次年3月1日。)

D和E合并步骤-替代方法

在第一次使用之前,设置L=[0,31,61,92,122,153,184,214,245,275,306,337]

(这是每月第一天之前(调整后)一年中累积天数的表格。)

将L[M]添加到D。

步骤F 如果您使用儒略历日期而不是公历日期,请跳过此步骤;转换因国家而异,但在大多数英语国家为1752年9月3日,在欧洲大部分地区为1582年10月4日。

如果您确定永远不必处理1900年3月1日至2100年2月28日范围之外的日期,您也可以跳过此步骤,但您必须对处理的所有日期做出相同的选择。

将Y除以100得到商Q和余数R,将Q除以4得到另一个商Q并忽略余数。

将R赋值给Y。

步骤G。 将Y除以4得到商Q,忽略余数。将Q+365×Y添加到D。

步骤H.(可选) 您可以将您选择的常量添加到D,以强制特定日期具有特定的天数。

对每个日期执行步骤A~G,得到D和D 2。

第一步。 从D 2中减去D,得到D 2在D之后的天数。

最后,评论:在处理1760年之前的日期时要格外小心,因为没有就哪个月是一年的开始达成一致;许多地方将3月1日视为新年。