2008-09-30 103 views
46

如何在幾天,幾小時,幾周或幾個月後迭代時間跨度?如何在Python中的幾天,幾小時,幾周和幾個月後迭代時間跨度?

喜歡的東西:

for date in foo(from_date, to_date, delta=HOURS): 
    print date 

其中foo是一個函數,返回一個迭代器。我一直在看日曆模塊,但只適用於特定的一年或一個月,而不是日期之間。

+0

或者,您是否想要帶有上述簽名的功能? – 2008-09-30 15:56:00

回答

75

使用dateutil及其RRULE實施,像這樣:

from dateutil import rrule 
from datetime import datetime, timedelta 

now = datetime.now() 
hundredDaysLater = now + timedelta(days=100) 

for dt in rrule.rrule(rrule.MONTHLY, dtstart=now, until=hundredDaysLater): 
    print dt 

輸出是

2008-09-30 23:29:54 
2008-10-30 23:29:54 
2008-11-30 23:29:54 
2008-12-30 23:29:54 

用MONEYLY,MONTHLY,WEEKLY,DAILY,HOURLY,MINUTELY或SECONDLY中的任何一個替換MONTHLY。將dtstart替換爲你想要的任何datetime對象。

這個配方在所有情況下都有優勢,包括MONTHLY。唯一需要注意的是,如果你通過一個不存在所有月份的日數,它會跳過那幾個月。

38

我不認爲這是在Python庫的方法,但你可以輕鬆地創建使用datetime模塊自己一:

from datetime import date, datetime, timedelta 

def datespan(startDate, endDate, delta=timedelta(days=1)): 
    currentDate = startDate 
    while currentDate < endDate: 
     yield currentDate 
     currentDate += delta 

然後,你可以使用這樣的:

>>> for day in datespan(date(2007, 3, 30), date(2007, 4, 3), 
>>>      delta=timedelta(days=1)): 
>>>  print day 
2007-03-30 
2007-03-31 
2007-04-01 
2007-04-02 

或者,如果你想使你的小三角:

>>> for timestamp in datespan(datetime(2007, 3, 30, 15, 30), 
>>>       datetime(2007, 3, 30, 18, 35), 
>>>       delta=timedelta(hours=1)): 
>>>  print timestamp 
2007-03-30 15:30:00 
2007-03-30 16:30:00 
2007-03-30 17:30:00 
2007-03-30 18:30:00 
+1

你不能指定一個月的timedelta – dangonfast 2014-08-06 12:02:14

6

對於迭代數月,您需要不同的配方,因爲timedeltas不能表達「一個月」。

from datetime import date 

def jump_by_month(start_date, end_date, month_step=1): 
    current_date = start_date 
    while current_date < end_date: 
     yield current_date 
     carry, new_month = divmod(current_date.month - 1 + month_step, 12) 
     new_month += 1 
     current_date = current_date.replace(year=current_date.year + carry, 
              month=new_month) 

(注:你必須從一個月減1爲模運算,然後在datetime.date S啓動在1加回new_month,因爲個月)

+0

有兩件事: - 如果你設置start_date的日期爲每個月不存在的數字,此代碼會引發`ValueError` - 可能正是因爲這個原因,沒有月份-timedelta;我建議使用`timedelta(days = 30)`作爲一個很好的近似值。 – DzinX 2008-09-30 17:29:24

+0

好的。然而,有時候,近似值不夠好(我的「支付租金」提醒*在每個月的第一天時間爲6點30分)。配方可以修改 - 可能有一些額外的狀態 - 以提供理智的功能,不管是什麼。 – giltay 2008-10-02 14:53:24

-2

您應修改這一行,使這項工作正確:

CURRENT_DATE = current_date.replace(年= current_date.year +攜帶,一個月= new_month,天= 1)

;)

0

月迭代方法:

def months_between(date_start, date_end): 
    months = [] 

    # Make sure start_date is smaller than end_date 
    if date_start > date_end: 
     tmp = date_start 
     date_start = date_end 
     date_end = tmp 

    tmp_date = date_start 
    while tmp_date.month <= date_end.month or tmp_date.year < date_end.year: 
     months.append(tmp_date) # Here you could do for example: months.append(datetime.datetime.strftime(tmp_date, "%b '%y")) 

     if tmp_date.month == 12: # New year 
      tmp_date = datetime.date(tmp_date.year + 1, 1, 1) 
     else: 
      tmp_date = datetime.date(tmp_date.year, tmp_date.month + 1, 1) 
    return months 

更多的代碼,但它會做得很好的交易,隨着時間檢查長期給定日期是爲了...

相關問題