我想datetime
在2015-11-02和2015-12-14之间找到所有星期二和星期三(作为对象).这有效:
from datetime import datetime, timedelta l = [] for i in range(100): d = datetime(2015,11,2) + timedelta(days=i) if d > datetime(2015,12,14): break if d.weekday() == 1 or d.weekday() == 2: # tuesday or wednesday l.append(d) print l
[datetime.datetime(2015,11,3,0,0),datetime.datetime(2015,11,4,0,0),datetime.datetime(2015,11,10,0,0),datetime.datetime( 2015,11,11,0,0),datetime.datetime(2015,11,17,0,0),datetime.datetime(2015,11,18,0,0),datetime.datetime(2015,11,24) ,0,0),datetime.datetime(2015,11,25,0,0),datetime.datetime(2015,12,1,0,0),datetime.datetime(2015,12,2,0,0) ,datetime.datetime(2015,12,8,0,0),datetime.datetime(2015,12,9,0,0)]
有更多的pythonic方式吗?
from datetime import datetime, timedelta start, end = datetime(2015, 11, 2), datetime(2015, 12, 14) days = (start + timedelta(days=i) for i in range((end - start).days + 1)) l = [d for d in days if d.weekday() in [1,2] ]
如果你需要很长的时间,这将会快得多:
def helper(d, i, inc): while d.weekday() != i: d += timedelta(days=inc) return d.replace(hour=0, minute=0, second=0, microsecond=0) start, end = datetime(2015, 11, 02), datetime(2015,12, 14) def find_days(st, end, d1, d2): if st >= end: raise ValueError("Start must be before end") else: _st, _end = helper(st, d1, inc=-1), helper(end, d2, 1) secs = (_end - _st).total_seconds() // 86400 if st.weekday() == d2: yield st for i in range(int(secs / 7) + 1): if st <= _st <= end: yield _st nxt = _st + timedelta(days=1) if nxt <= end: yield nxt _st += timedelta(days=7) if _st <= end: yield _st from pprint import pprint as pp from pprint import pprint as pp pp(list(find_days(start, end, 1, 2)))
输出:
[datetime.datetime(2015, 11, 3, 0, 0), datetime.datetime(2015, 11, 4, 0, 0), datetime.datetime(2015, 11, 10, 0, 0), datetime.datetime(2015, 11, 11, 0, 0), datetime.datetime(2015, 11, 17, 0, 0), datetime.datetime(2015, 11, 18, 0, 0), datetime.datetime(2015, 11, 24, 0, 0), datetime.datetime(2015, 11, 25, 0, 0), datetime.datetime(2015, 12, 1, 0, 0), datetime.datetime(2015, 12, 2, 0, 0), datetime.datetime(2015, 12, 8, 0, 0), datetime.datetime(2015, 12, 9, 0, 0)]
这就像dateutil那样做,并且做得更快:
In [12]: def dte(): ....: results = rrule(DAILY, ....: dtstart = dt.datetime(2015,11, 2), ....: until = end, ....: byweekday=(TU, WE), ....: ) ....: return list(results) ....: In [38]: start, end = datetime(2015, 11, 2), datetime(2100, 11, 14) In [39]: for i in range(600): end += timedelta(days=1) assert dte() == list(find_days(start, end,1,2 )) ....: In [40]: start, end = datetime(2015, 11, 2), datetime(2017, 11, 14) In [41]: timeit [d for d in date_range(start, end) if d.weekday() in (1, 2)] 10 loops, best of 3: 62.1 ms per loop In [42]: timeit list(find_days(start, end, 1, 2)) 100 loops, best of 3: 8.11 ms per loop In [43]: timeit dte() 10 loops, best of 3: 131 ms per loop