引用给定的开始日期时间和结束日期时间的月份中某一天的每次出现



正如标题所说,我正在尝试生成一个日期时间列表,对应于两个日期之间每月特定日期的出现次数。

因此,给定开始日期、结束日期和每月的某一天,我希望看到该月该天出现的每一个事件:

from datetime import datetime
end_date = datetime(2012, 9, 15, 0, 0)
start_date = datetime(2012, 6, 1, 0, 0)
day_of_month = 16
dates = "magic code goes here"

然后,日期将保存一个数组,如下所示:

dates == [
datetime(2012, 6, 16, 0, 0),
datetime(2012, 7, 16, 0, 0),
datetime(2012, 8, 16, 0, 0)
]

遇到的问题是我必须执行的检查数量。首先,我必须检查它是否是开始年份,如果是,那么我必须从开始月份开始,但如果该月中的某一天在开始日期之前,那么我必须跳过该月。同样的事情也适用于期末。更不用说我必须检查该时期是否在同一年开始和结束。总而言之,它变成了一堆嵌套的iffor语句。

这是我的解决方案:

import numpy as np
for year in np.arange(start_date.year, end_date.year + 1):
    for month in np.arange(1, 13):
        date = datetime(year, month, day_of_month, 0, 0)
        if start_date < date < end_date:
            dates.append(date)

有没有更 Python 的方法来实现这一点?

这是一个快速而肮脏(但相当高效(的解决方案:

import datetime
d = start_date
days = []
while d <= end_date: # Change to < if you do not want the end_date
    if d.day == day_of_month:
        days.append(d)
    d += datetime.timedelta(1)
days
# [datetime.datetime(2012, 6, 16, 0, 0), 
#  datetime.datetime(2012, 7, 16, 0, 0), 
#  datetime.datetime(2012, 8, 16, 0, 0)]

理想情况下,您希望为此使用pandas

这是一种

简洁但效率不高的方法,使用pandas.date_range

from datetime import datetime
import pandas as pd
end_date = datetime(2012, 9, 15, 0, 0)
start_date = datetime(2012, 6, 1, 0, 0)
day_of_month = 16
rng = [i.to_pydatetime() for i in pd.date_range(start_date, end_date, freq='1D') if i.day == day_of_month]
# [datetime.datetime(2012, 6, 16, 0, 0),
#  datetime.datetime(2012, 7, 16, 0, 0),
#  datetime.datetime(2012, 8, 16, 0, 0)]

这是一种更有效的方法,使用日期范围的生成器,不依赖于pandas

def daterange(start_date, end_date):
    for n in range(int ((end_date - start_date).days)):
        yield start_date + timedelta(n)
rng = [i for i in daterange(start_date, end_date) if i.day == day_of_month]
# [datetime.datetime(2012, 6, 16, 0, 0),
#  datetime.datetime(2012, 7, 16, 0, 0),
#  datetime.datetime(2012, 8, 16, 0, 0)]

最新更新