有很多关于找到两个日期之间的差异的帖子,但涉及的值的开头和结尾的格式与我使用的格式不同,例如:
a = 01/01/10 # dd/mm/yy format
b = 01/01/05 # dd/mm/yy format
所以我追踪a和b之间的年,月和日的差异,其中所需的输出格式为x years, x months, x days (if required)
格式。
我正在阅读datetime documentation并且已经有了解决它的问题(请注意:未来肯定是新手代码,我试图将所有演示文件拼凑在一起,因此必须进行一些修改):< / p>
from datetime import datetime as dt
# calculate duration between two dates
# later date
later_date = '01/01/10'.replace('/', '')
# reverse the order
later_date = "".join(reversed([later_datet[i:i+2] for i in range(0, len(later_date), 2)]))
# separate with commas every two numbers
later_date = ','.join(later_date[i:i+2] for i in range(0, len(later_date), 2))
# convert to datetime object
later_date = dt.strptime(later_date, "%y,%m,%d")
# earlier date
earlier_date = '01/01/05'.replace('/','')
# reverse the order
earlier_date = "".join(reversed([earlier_date[i:i+2] for i in range(0, len(earlier_date), 2)]))
# separate with commas every two numbers
earlier_date = ','.join(earlier_date[i:i+2] for i in range(0, len(earlier_date), 2))
# convert to datetime object
earlier_date = dt.strptime(earlier_date, "%y,%m,%d")
duration = later date - earlier_date
print duration
print type(duration)
正在输出:
1826 days, 0:00:00
<type 'datetime.timedelta'>
所以我认为我有点接近获取正确的数据,但现在我需要将其转换为x years, x months, x days (if required)
格式。
修改/解决方案:
我已将一些代码放在一起并正在测试,我认为它适用于所有日期组合但如果有人注意到错误,请告诉我们:
"""
this code calculates the duration between two dates (a later and earlier date)
in the format dd/mm/yy and returns the duration in years, months and days with
correct formatting in regards to the plurality of the year/s, month/s, and day/s
and the punctuation required dependent on whether one or more values are returned
ie multiple values are separated by ',' whereas a singular value is terminated by '.'.
"""
# imported libraries
from datetime import datetime as dt
from dateutil import relativedelta
import sys
# initial date objects
later_date = '01/01/10'
earlier_date = '01/01/05'
# convert dates to required format
a_date = dt.strptime(later_date, '%d/%m/%y')
b_date = dt.strptime(earlier_date, '%d/%m/%y')
# get duration using dateutil
duration = relativedelta.relativedelta(a_date, b_date)
# check if number of years is not false ie != 0
if duration.years != 0:
years = duration.years
else:
years = False
# check if number of months is not false ie != 0
if duration.months != 0:
months = duration.months
else:
months = False
# check if number of days is not false ie != 0
if duration.days != 0:
days = duration.days
else:
days = False
# add values to a list
date_list = [years,months,days]
# count instances of False in the list
false_count = date_list.count(False)
# iterate over list with enumeration performing value and
# boolean checking to predicate plurality and punctuality
# requirements.
for n, _ in enumerate(date_list):
# year/s - single or plural, lone value or more
if _ != False and n == 0:
single_year = date_list[0] == 1
# if single and not lone
if single_year == True and false_count != 2:
sys.stdout.write(str(_)+' year, ')
# if single and lone
elif single_year == True and false_count == 2:
sys.stdout.write(str(_)+' year.')
# if not single and not lone
elif single_year == False and false_count != 2:
sys.stdout.write(str(_)+' years, ')
# if not single but lone
elif single_year == False and false_count == 2:
sys.stdout.write(str(_)+' years.')
# if there are no years, still provide value for possible later concatenation
if _ == False and n == 0:
datasetduration_y = ''
# month/s - single or plural, lone value or more
if _ != False and n == 1:
single_month = date_list[1] == 1
# if single and not lone
if single_month == True and false_count != 2:
sys.stdout.write(str(_)+' month, ')
# if single and lone
elif single_month == True and false_count == 2:
sys.stdout.write(str(_)+' month.')
# if not single and not lone and there are days
elif single_month == False and false_count != 2 and date_list[2] != False:
sys.stdout.write(str(_)+' months, ')
# if not single and not lone and there are no days
elif single_month == False and false_count != 2 and date_list[2] == False:
sys.stdout.write(str(_)+' months.')
# if not single but lone
elif single_month == False and false_count == 2:
sys.stdout.write(str(_)+' months.')
# if there are no months, still provide value for possible later concatenation
if _ == False and n == 1:
datasetduration_m = ''
# day/s - single or plural, lone value or more
if _ != False and n == 2:
single_day = date_list[2] == 1
# if single and not lone
if single_day == True and false_count != 2:
sys.stdout.write(str(_)+' day.')
# if single and lone
elif single_day == True and false_count == 2:
sys.stdout.write(str(_)+' day.')
# if not single and not lone
elif single_day == False and false_count != 2:
sys.stdout.write(str(_)+' days.')
# if not single but lone
elif single_day == False and false_count == 2:
sys.stdout.write(str(_)+' days.')
# if there are no days, still provide value for possible later concatenation
if _ == False and n == 2:
datasetduration_d = ''
答案 0 :(得分:0)
好吧,我们走了。这不是与日期时间相关的解决方案。但是,我认为这仍然可以让你得到你所要求的......
Number of years: 1826/365
。看看整整多年过去了。
Number of months: (1826%365)/30
。剩下的几天,多少个月。 (这里,我们忽略了具体的月份长度(Jan = 31,Feb = 28等),只使用30天/月)。
Number of days: (1826%365)%30
。剩余的日子里,有多少天。
答案 1 :(得分:0)
这应该可以解决问题
>>> from datetime import datetime as dt
>>> a = '01/01/2010'
>>> b = '01/01/2005'
>>> a_date = dt.strptime(a, '%d/%m/%Y') # Use capital Y for year with century
>>> b_date = dt.strptime(b, '%d/%m/%Y')
>>> td = a_date - b_date
>>> td
datetime.timedelta(1826)
您现在有一个timedelta
对象,其中包含a
和b
之间的天数。
在数年,数月和数日表达这一点并不十分清楚,因为“年”或“月”或“日”都不是标准化的时间单位 - 年和月有不同的天数,天数可变秒数。在这种情况下,我认为最好留下以天为单位的差异,您可以通过
来获得>>> td.days
1826
如果您真的想表达天数,年数和月数,那么您可以按照以下方式运作
>>> nyears = a_date.year - b_date.year
>>> nmonths = a_date.month - b_data.month
>>> ndays = a_date.day - b_data.day
这会给你带来年,日,月的差异,但前提是它们可能是负面的。处理这个问题有几种选择。一种方法是允许天数,月数和年数的负差异(这具有完美的数学意义)。另一种选择是调整它们:
>>> if ndays < 0:
ndays = ndays + 30
nmonths = nmonths - 1
>>> if nmonths < 0:
nmonths = nmonths + 12
nyears = nyears - 1
答案 2 :(得分:0)
一个简单的回答:
years, remainder = divmod(duration.days, 365)
months, days = divmod(remainder, 30)
print "{} years, {} months {} days".format(years,months,days)