下面有更有效的方法吗?我希望将两个日期之间的年份差异作为单个标量.欢迎任何建议.
from datetime import datetime
start_date = datetime(2010,4,28,12,33)
end_date = datetime(2010,5,5,23,14)
difference = end_date - start_date
difference_in_years = (difference.days + difference.seconds/86400)/365.2425
Run Code Online (Sandbox Code Playgroud)
Kar*_*tel 73
如果您想要精确的结果,我建议使用dateutil库.
from dateutil.relativedelta import relativedelta
difference_in_years = relativedelta(end_date, start_date).years
Run Code Online (Sandbox Code Playgroud)
这是完整的年份(例如一个人的年龄).如果你想要小数年,那么添加几个月,几天,几小时......达到所需的精度.
Kos*_*tyn 13
我用其中一个来计算人的年龄:
import datetime
dob = datetime.date(1980, 10, 10)
def age():
today = datetime.date.today()
years = today.year - dob.year
if today.month < dob.month or (today.month == dob.month and today.day < dob.day):
years -= 1
return years
def age2():
today = datetime.date.today()
this_year_birthday = datetime.date(today.year, dob.month, dob.day)
if this_year_birthday < today:
years = today.year - dob.year
else:
years = today.year - dob.year - 1
return years
Run Code Online (Sandbox Code Playgroud)
更高效?不,但更正确,可能.但这取决于你想要的正确程度.日期不是琐碎的事情.
年份没有恒定的长度.你想要闰年或正常年份的差异吗?:-)按照你的计算,你总会得到一个稍微不正确的答案.多年的一天多长时间?你说1/365.2425.嗯,是的,平均超过一千年,是的.但否则不是.
所以问题并没有多大意义.
要纠正你必须这样做:
from datetime import datetime
from calendar import isleap
start_date = datetime(2005,4,28,12,33)
end_date = datetime(2010,5,5,23,14)
diffyears = end_date.year - start_date.year
difference = end_date - start_date.replace(end_date.year)
days_in_year = isleap(end_date.year) and 366 or 365
difference_in_years = diffyears + (difference.days + difference.seconds/86400.0)/days_in_year
Run Code Online (Sandbox Code Playgroud)
在这种情况下,这是相差0.0012322917425568528年,或0.662天,考虑到这不是闰年.
(然后我们忽略了微秒.嘿.)
这样做:
from dateutil.relativedelta import relativedelta
myBirthday = datetime.datetime(1983,5,20,0,0,0,0)
now = datetime.datetime.now()
difference = relativedelta(now, myBirthday)
print("My years: "+str(difference.years))
Run Code Online (Sandbox Code Playgroud)
为了理解闰年,你几乎被迫把它分成两部分:整数年,一部分.两者都需要处理闰年,但需要以不同的方式 - 处理2月29日开始日期的整体需求,而小数必须处理一年中不同的天数.您希望小数部分以相等的数量递增,直到它在下一个周年日等于1.0,因此它应该基于结束日期之后一年中的天数.
您希望您的日期范围包括1900或2100吗?如果你不这样做,事情会变得容易些.
2008-02-28和2009-02-28之间有什么区别?大多数人都会同意这应该是1.0年.2008-03-01和2009-03-01之间的区别怎么样?同样,大多数人都会同意它应该正好是1.0年.如果您选择将日期表示为年份加上基于当天的一年中的一小部分,则无法使这两个陈述成立.原始代码的情况就是这样,假设一天是一年的1/365.2425,或者实际上对于假设每天一年的常数分数的任何代码,即使一天的大小占了飞跃的年份年份.
我断言你需要将其分解为整数年和分数年,这是试图解决这个问题.如果您将之前的每个条件视为一个完整的年份,那么您所要做的就是决定分配给剩余天数的分数.这个方案的问题在于你仍然无法理解(date2-date1)+ date3,因为无法将分数解析回具有任何一致性的一天.
因此,我提议另一种编码,基于每年包含366天,无论是否是闰年.异常将首先是从2月29日开始的日期不是一年(或2或3) - "对不起约翰尼,你今年没有生日,没有2月29日"总是可以接受的.其次,如果你试图强迫这样的数字回到日期,你将不得不考虑非闰年并检查2月29日的特殊情况并将其转换,可能是3月1日.
from datetime import datetime
from datetime import timedelta
from calendar import isleap
size_of_day = 1. / 366.
size_of_second = size_of_day / (24. * 60. * 60.)
def date_as_float(dt):
days_from_jan1 = dt - datetime(dt.year, 1, 1)
if not isleap(dt.year) and days_from_jan1.days >= 31+28:
days_from_jan1 += timedelta(1)
return dt.year + days_from_jan1.days * size_of_day + days_from_jan1.seconds * size_of_second
start_date = datetime(2010,4,28,12,33)
end_date = datetime(2010,5,5,23,14)
difference_in_years = date_as_float(end_time) - date_as_float(start_time)
Run Code Online (Sandbox Code Playgroud)
我并不是说,这是该解决方案,因为我不认为一个完美的解决方案是可能的.但它有一些理想的属性:
| 归档时间: |
|
| 查看次数: |
45573 次 |
| 最近记录: |