我想创建一个日期列表,从今天开始,追溯到任意天数,例如,在我的示例中是100天。还有比这更好的办法吗?

import datetime

a = datetime.datetime.today()
numdays = 100
dateList = []
for x in range (0, numdays):
    dateList.append(a - datetime.timedelta(days = x))
print dateList

当前回答

你可以写一个生成器函数,返回从今天开始的日期对象:

import datetime

def date_generator():
  from_date = datetime.datetime.today()
  while True:
    yield from_date
    from_date = from_date - datetime.timedelta(days=1)

这个生成器返回从今天开始的日期,一次返回一天。以下是前3次约会的方法:

>>> import itertools
>>> dates = itertools.islice(date_generator(), 3)
>>> list(dates)
[datetime.datetime(2009, 6, 14, 19, 12, 21, 703890), datetime.datetime(2009, 6, 13, 19, 12, 21, 703890), datetime.datetime(2009, 6, 12, 19, 12, 21, 703890)]

与循环或列表推导相比,这种方法的优点是可以返回任意多次。

Edit

使用生成器表达式代替函数的更紧凑的版本:

date_generator = (datetime.datetime.today() - datetime.timedelta(days=i) for i in itertools.count())

用法:

>>> dates = itertools.islice(date_generator, 3)
>>> list(dates)
[datetime.datetime(2009, 6, 15, 1, 32, 37, 286765), datetime.datetime(2009, 6, 14, 1, 32, 37, 286836), datetime.datetime(2009, 6, 13, 1, 32, 37, 286859)]

其他回答

如果有两个日期,你需要范围试试

from dateutil import rrule, parser
date1 = '1995-01-01'
date2 = '1995-02-28'
datesx = list(rrule.rrule(rrule.DAILY, dtstart=parser.parse(date1), until=parser.parse(date2)))

从这个问题的标题中,我希望找到类似range()的东西,这将让我指定两个日期并创建一个包含所有日期的列表。这样,如果事先不知道,就不需要计算这两个日期之间的天数。

所以,冒着有点跑题的风险,这句话就可以了:

import datetime
start_date = datetime.date(2011, 1, 1)
end_date   = datetime.date(2014, 1, 1)

dates_2011_2013 = [ start_date + datetime.timedelta(n) for n in range(int ((end_date - start_date).days))]

所有功劳都归于这个答案!

稍微更好……

base = datetime.datetime.today()
date_list = [base - datetime.timedelta(days=x) for x in range(numdays)]

一个泛型方法,允许在参数化窗口大小(天,分钟,小时,秒)上创建日期范围:

from datetime import datetime, timedelta

def create_date_ranges(start, end, **interval):
    start_ = start
    while start_ < end:
        end_ = start_ + timedelta(**interval)
        yield (start_, min(end_, end))
        start_ = end_

测试:

def main():
    tests = [
        ('2021-11-15:00:00:00', '2021-11-17:13:00:00', {'days': 1}),
        ('2021-11-15:00:00:00', '2021-11-16:13:00:00', {'hours': 12}),
        ('2021-11-15:00:00:00', '2021-11-15:01:45:00', {'minutes': 30}),
        ('2021-11-15:00:00:00', '2021-11-15:00:01:12', {'seconds': 30})
    ]
    for t in tests:
        print("\nInterval: %s, range(%s to %s)" % (t[2], t[0], t[1]))
        start = datetime.strptime(t[0], '%Y-%m-%d:%H:%M:%S')
        end =  datetime.strptime(t[1], '%Y-%m-%d:%H:%M:%S')
        ranges = list(create_date_ranges(start, end, **t[2]))        
        x = list(map(
            lambda x: (x[0].strftime('%Y-%m-%d:%H:%M:%S'), x[1].strftime('%Y-%m-%d:%H:%M:%S')),
            ranges
        ))
        print(x)
main()

测试输出:

Interval: {'days': 1}, range(2021-11-15:00:00:00 to 2021-11-17:13:00:00)
[('2021-11-15:00:00:00', '2021-11-16:00:00:00'), ('2021-11-16:00:00:00', '2021-11-17:00:00:00'), ('2021-11-17:00:00:00', '2021-11-17:13:00:00')]

Interval: {'hours': 12}, range(2021-11-15:00:00:00 to 2021-11-16:13:00:00)
[('2021-11-15:00:00:00', '2021-11-15:12:00:00'), ('2021-11-15:12:00:00', '2021-11-16:00:00:00'), ('2021-11-16:00:00:00', '2021-11-16:12:00:00'), ('2021-11-16:12:00:00', '2021-11-16:13:00:00')]

Interval: {'minutes': 30}, range(2021-11-15:00:00:00 to 2021-11-15:01:45:00)
[('2021-11-15:00:00:00', '2021-11-15:00:30:00'), ('2021-11-15:00:30:00', '2021-11-15:01:00:00'), ('2021-11-15:01:00:00', '2021-11-15:01:30:00'), ('2021-11-15:01:30:00', '2021-11-15:01:45:00')]

Interval: {'seconds': 30}, range(2021-11-15:00:00:00 to 2021-11-15:00:01:12)
[('2021-11-15:00:00:00', '2021-11-15:00:00:30'), ('2021-11-15:00:00:30', '2021-11-15:00:01:00'), ('2021-11-15:00:01:00', '2021-11-15:00:01:12')]

一个带有datetime和dateutil的月日期范围生成器。简单易懂的:

import datetime as dt
from dateutil.relativedelta import relativedelta

def month_range(start_date, n_months):
        for m in range(n_months):
            yield start_date + relativedelta(months=+m)