如何找到'dd / mm / yy'格式的两个日期之间y-m-d的差异?

时间:2013-05-26 10:33:08

标签: python datetime python-2.7

有很多关于找到两个日期之间的差异的帖子,但涉及的值的开头和结尾的格式与我使用的格式不同,例如:

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 = ''

3 个答案:

答案 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对象,其中包含ab之间的天数。

在数年,数月和数日表达这一点并不十分清楚,因为“年”或“月”或“日”都不是标准化的时间单位 - 年和月有不同的天数,天数可变秒数。在这种情况下,我认为最好留下以天为单位的差异,您可以通过

来获得
>>> 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)