如果我有两个日期(例如 '8/18/2008'
和'9/26/2008'
),获取这两个日期之间的天数的最佳方法是什么?
如果有两个日期对象,只需减去它们,即可计算出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。
有关另一个示例,请参阅此答案。
使用日期时间的力量:
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 how to calculate number of days between two given dates
圣诞节前几天:
>>> import datetime
>>> today = datetime.date.today()
>>> someday = datetime.date(2008, 12, 25)
>>> diff = someday - today
>>> diff.days
86
这里更多的算术。
每个人都使用日期出色地回答了,让我尝试用熊猫来回答它
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
您需要日期时间模块。
>>> from datetime import datetime
>>> 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)
也可以使用 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/
不使用 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 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)
# week
results = date_only - dateutil.relativedelta.relativedelta(weeks=1)
# days
result = date_only - dateutil.relativedelta.relativedelta(days=10)
# calculate time
result = date_and_time - timedelta(hours=26, minutes=25, seconds=10)
result.time()
希望对你有帮助
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+'
.
还有一个尚未提及的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.
toordinal()返回日期的外推公历序数,其中第 1 年的 1 月 1 日具有序数 1。对于任何
date
对象 d,date.fromordinal(d.toordinal()) == d
.
似乎非常适合计算天差,尽管不像timedelta.days
那样可读。
这里有三种方法可以解决这个问题:
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
如果你想自己编写计算代码,那么这里有一个函数,它将返回给定年份、月份和日期的序数:
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))
此函数与日期时间模块中的date.toordinal
方法兼容。
您可以获取两个日期之间的差天数,如下所示:
print(ordinal(2021, 5, 10) - ordinal(2001, 9, 11))
在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")
如果你没有日期处理库(或者你怀疑它有错误),这里有一个抽象算法,应该很容易翻译成大多数语言。
在每个日期执行以下计算,然后简单地减去两个结果。所有商和余数都是正整数。
步骤A.首先将日期的各个部分标识为Y(年),M(月)和D(日)。这些变量会随着我们的发展而变化。
步骤 B. 从 M 中减去 3
(因此 1 月是 -2,12 月是 9)。
步骤C。如果 M 为负数,则在 M 上加 12,然后从 Y 年中减去 1。
(这会将"年初"更改为 3 月 1 日,月份编号为 0(3 月)到 11(2 月)。这样做的原因是为了让"一年内的日数"在闰年和普通年之间不会发生变化,并且"短"月份在年底,因此没有下一个月份需要特殊处理。
步骤 D.将 M 除以 5 得到商 Q₁ 和余数 R₁。将 Q₁ × 153 添加到 D。在下一步中使用 R₁。
(从3月1日开始,每5个月有153天。
步骤 E. 将 R₁ 除以 2 得到商 Q₂ 并忽略余数。将 R₁ × 31 - Q₂ 添加到 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₄ 并忽略余数。将 Q₄ + 36524 × Q₃ 添加到 D。
将 R₃ 分配给 Y。
步骤 G.将 Y 除以 4 得到商 Q₅ 并忽略余数。将 Q₅ + 365 × Y 添加到 D。
步骤 H. (可选)您可以将您选择的常量添加到 D,以强制特定日期具有特定的日期编号。
为每个日期执行步骤 A~G,得到 D₁ 和 D₂。
步骤一.从 D₂ 中减去 D₁ 得到 D₂ 在 D₁ 之后的天数。
最后,评论一下:在处理大约1760年之前的日期时要格外小心,因为对于哪个月份是一年的开始没有达成一致;许多地方将3月1日视为新年。
起点和终点之间的每个日历日都有一个日期对象,那么这段代码可能会有所帮助。它返回开始和结束之间每天的日期对象:
from math import ceil
from datetime import date, datetime, timedelta
def day_range(start: datetime, end: datetime) -> date:
first_day = start.replace(hour=0, minute=0, second=0, microsecond=0)
daycount = ceil((end - first_day) / timedelta(days=1))
for n in range(daycount):
yield (start + timedelta(days=n)).date()
start = datetime(2023, 1, 1, 23, 0)
end = datetime(2023, 1, 4, 0, 20)
for day in day_range(start, end):
print(f"Day: {day}")