如何创建一个日期范围,直到包含 python dateutils 的某个日期?
How to create a date range until some date inclusive with python dateutils?
我正在尝试获取给定范围内的月份列表。具体来说,给定范围 2015-12-31 - 2016-01-01
,我想获取列表 2015-12
和 2016-01
.
我正在使用 dateutil 的规则,但 until
参数并没有真正帮助,因为它似乎正在寻找完整的月份。
例如:
from dateutil.relativedelta import relativedelta
from dateutil.rrule import rrule, MONTHLY
list(rrule(MONTHLY, dtstart=datetime(2015, 12, 31), until=datetime(2016,01,01)))
这只有returns[datetime.datetime(2015, 12, 31, 0, 0)]
,没有[datetime.datetime(2015, 12, 31, 0, 0), datetime.datetime(2016, 01, 01, 0, 0)]
同样,我希望 12 月的任何开始日和 1 月的任何结束日都具有相同的输出。也就是说,我只关心月份是2015-12
和2016-01
。日部分对我来说并不重要,但我每月只想要一个 datetime
(这些输入最多 2 个,day
组件的任何值)。
是否有一个简单的解决方案,或者我是否必须每天递增并构建我自己的月份集?
我已经用集合完成了:
months = set()
for dt in rrule(DAILY, dtstart=start_date, until=end_date):
months.add(dt.strftime('%Y-%m-.*'))
我认为您将不得不执行某种迭代。例如,使用 deltas
,下面的方法就可以了:
import datetime
start = datetime.datetime(2015, 12, 31)
stop = datetime.datetime(2016, 1, 8)
delta = stop - start
answer = [start+datetime.timedelta(days=idx) for idx in range(delta.days+1)]
print(answer)
输出
[datetime.datetime(2015, 12, 31, 0, 0),
datetime.datetime(2016, 1, 1, 0, 0),
datetime.datetime(2016, 1, 2, 0, 0),
datetime.datetime(2016, 1, 3, 0, 0),
datetime.datetime(2016, 1, 4, 0, 0),
datetime.datetime(2016, 1, 5, 0, 0),
datetime.datetime(2016, 1, 6, 0, 0),
datetime.datetime(2016, 1, 7, 0, 0),
datetime.datetime(2016, 1, 8, 0, 0)]
您的 list(rrule(MONTHLY, dtstart=datetime(2015, 12, 31), until=datetime(2016,01,01)))
不是 return 1 月的原因是因为在 12 月 31 日和 1 月 1 日之间没有一个月(基于 MONTHLY
参数)。
由于您不需要日期组件,我将执行一些日期操作:
def date_list(start, end):
start = datetime.date(start.year, start.month, 1)
end = datetime.date(end.year, end.month, 1)
dates = [dt for dt in rrule(MONTHLY, dtstart=start, until=end)]
return dates
这样做是接受任何开始和结束日期,然后将这两个日期重置为该月的第一天。这确保存在一个完整的月份。它将 return 一个日期列表,每个日期都是该月的第一天。
例如,根据您的输入
>>> print date_list(datetime.date(2015,12,28), datetime.date(2016,1,1))
[datetime.datetime(2015, 12, 1, 0, 0), datetime.datetime(2016, 1, 1, 0, 0)]
同月:
>>> print date_list(datetime.date(2015,12,28), datetime.date(2015,12,31))
[datetime.datetime(2015, 12, 1, 0, 0)]
范围无效(开始前结束):
>>> print date_list(datetime.date(2015,12,28), datetime.date(2015,11,30))
[]
射程更远:
>>> print date_list(datetime.date(2015,12,28), datetime.date(2016,8,3))
[datetime.datetime(2015, 12, 1, 0, 0),
datetime.datetime(2016, 1, 1, 0, 0),
datetime.datetime(2016, 2, 1, 0, 0),
datetime.datetime(2016, 3, 1, 0, 0),
datetime.datetime(2016, 4, 1, 0, 0),
datetime.datetime(2016, 5, 1, 0, 0),
datetime.datetime(2016, 6, 1, 0, 0),
datetime.datetime(2016, 7, 1, 0, 0),
datetime.datetime(2016, 8, 1, 0, 0)]
只用月数之差来计算:
start = datetime(2015, 12, 31)
end = datetime(2016,01,01)
diff_month = lambda e, s: (e.year - s.year)*12 + e.month - s.month
list(rrule(MONTHLY, count=diff_month(end,start)+1, dtstart=start))
我正在尝试获取给定范围内的月份列表。具体来说,给定范围 2015-12-31 - 2016-01-01
,我想获取列表 2015-12
和 2016-01
.
我正在使用 dateutil 的规则,但 until
参数并没有真正帮助,因为它似乎正在寻找完整的月份。
例如:
from dateutil.relativedelta import relativedelta
from dateutil.rrule import rrule, MONTHLY
list(rrule(MONTHLY, dtstart=datetime(2015, 12, 31), until=datetime(2016,01,01)))
这只有returns[datetime.datetime(2015, 12, 31, 0, 0)]
,没有[datetime.datetime(2015, 12, 31, 0, 0), datetime.datetime(2016, 01, 01, 0, 0)]
同样,我希望 12 月的任何开始日和 1 月的任何结束日都具有相同的输出。也就是说,我只关心月份是2015-12
和2016-01
。日部分对我来说并不重要,但我每月只想要一个 datetime
(这些输入最多 2 个,day
组件的任何值)。
是否有一个简单的解决方案,或者我是否必须每天递增并构建我自己的月份集?
我已经用集合完成了:
months = set()
for dt in rrule(DAILY, dtstart=start_date, until=end_date):
months.add(dt.strftime('%Y-%m-.*'))
我认为您将不得不执行某种迭代。例如,使用 deltas
,下面的方法就可以了:
import datetime
start = datetime.datetime(2015, 12, 31)
stop = datetime.datetime(2016, 1, 8)
delta = stop - start
answer = [start+datetime.timedelta(days=idx) for idx in range(delta.days+1)]
print(answer)
输出
[datetime.datetime(2015, 12, 31, 0, 0),
datetime.datetime(2016, 1, 1, 0, 0),
datetime.datetime(2016, 1, 2, 0, 0),
datetime.datetime(2016, 1, 3, 0, 0),
datetime.datetime(2016, 1, 4, 0, 0),
datetime.datetime(2016, 1, 5, 0, 0),
datetime.datetime(2016, 1, 6, 0, 0),
datetime.datetime(2016, 1, 7, 0, 0),
datetime.datetime(2016, 1, 8, 0, 0)]
您的 list(rrule(MONTHLY, dtstart=datetime(2015, 12, 31), until=datetime(2016,01,01)))
不是 return 1 月的原因是因为在 12 月 31 日和 1 月 1 日之间没有一个月(基于 MONTHLY
参数)。
由于您不需要日期组件,我将执行一些日期操作:
def date_list(start, end):
start = datetime.date(start.year, start.month, 1)
end = datetime.date(end.year, end.month, 1)
dates = [dt for dt in rrule(MONTHLY, dtstart=start, until=end)]
return dates
这样做是接受任何开始和结束日期,然后将这两个日期重置为该月的第一天。这确保存在一个完整的月份。它将 return 一个日期列表,每个日期都是该月的第一天。
例如,根据您的输入
>>> print date_list(datetime.date(2015,12,28), datetime.date(2016,1,1))
[datetime.datetime(2015, 12, 1, 0, 0), datetime.datetime(2016, 1, 1, 0, 0)]
同月:
>>> print date_list(datetime.date(2015,12,28), datetime.date(2015,12,31))
[datetime.datetime(2015, 12, 1, 0, 0)]
范围无效(开始前结束):
>>> print date_list(datetime.date(2015,12,28), datetime.date(2015,11,30))
[]
射程更远:
>>> print date_list(datetime.date(2015,12,28), datetime.date(2016,8,3))
[datetime.datetime(2015, 12, 1, 0, 0),
datetime.datetime(2016, 1, 1, 0, 0),
datetime.datetime(2016, 2, 1, 0, 0),
datetime.datetime(2016, 3, 1, 0, 0),
datetime.datetime(2016, 4, 1, 0, 0),
datetime.datetime(2016, 5, 1, 0, 0),
datetime.datetime(2016, 6, 1, 0, 0),
datetime.datetime(2016, 7, 1, 0, 0),
datetime.datetime(2016, 8, 1, 0, 0)]
只用月数之差来计算:
start = datetime(2015, 12, 31)
end = datetime(2016,01,01)
diff_month = lambda e, s: (e.year - s.year)*12 + e.month - s.month
list(rrule(MONTHLY, count=diff_month(end,start)+1, dtstart=start))