12

週末(そして休日もいいでしょう!)をスキップして、営業日(平日)にわたって反復するジェネレーター関数を作成しようとしています。これまでのところ、私は単に何日も繰り返す関数しか持っていません。

def daterange(startDate, endDate):
    for i in xrange(int((endDate - startDate).days)):
        yield startDate + timedelta(i)

ジェネレーターを週末と休日にスキップさせるための、クリーンで効率的でPythonのような方法を見つけるのに苦労しています。前もって感謝します!

4

5 に答える 5

27

このようなタスクにはdateutilライブラリを使用することを強くお勧めします。営業日にわたる基本的な(休日を無視しない)イテレータは、単純に次のとおりです。

from dateutil.rrule import DAILY, rrule, MO, TU, WE, TH, FR

def daterange(start_date, end_date):
  return rrule(DAILY, dtstart=start_date, until=end_date, byweekday=(MO,TU,WE,TH,FR))
于 2012-07-18T21:11:58.220 に答える
11

が日時オブジェクトまたは日付オブジェクトであるとすると、このメソッドを使用startDate曜日を取得し、土曜日または日曜日の場合はスキップできます。ただ行う:endDateweekday

def daterange(startDate, endDate):
    for i in xrange(int((endDate - startDate).days)):
        nextDate = startDate + timedelta(i)
        if nextDate.weekday() not in (5, 6):
            yield startDate + timedelta(i)

休日の場合は、希望する休日ごとに手動で確認する必要があります。一部の休日は複雑な方法で定義されているため、これは少し注意が必要です。

于 2012-07-18T21:09:39.543 に答える
9

Python pandasには、デフォルトの頻度としてBusiness Daysを使用するbdate_range()メソッドが組み込まれています。 https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.bdate_range.html

import pandas as pd
pd.bdate_range(start='1/25/2020', end='2/24/2020')
于 2020-03-06T22:28:43.187 に答える
7

dateutilこの種のことをあなたのために行うことができると呼ばれる便利なライブラリがあります。特定の日を除く日付の範囲(またはカスタムルールに基づく日付)を生成したり、1日から始まる週を考慮したりできます。また、組み込みの日時ライブラリよりも多少柔軟なタイムデルタがあります。

ドキュメントはhttp://labix.org/python-dateutil/にあり、PyPiで入手できます。

于 2012-07-18T21:09:56.483 に答える
1
def get_date_range(start, end, workdays=None, holidays=None, skip_non_workdays=True):
"""
This function calculates the durations between 2 dates skipping non workdays and holidays as specified
:rtype : tuple
:param start: date
:param end: date
:param workdays: string [Comma Separated Values, 0 - Monday through to 6 - Sunday e.g "0,1,2,3,4"]
:param holidays: list
:param skip_non_workdays: boolean
:return:
"""
from datetime import timedelta

duration = 0

# define workdays
if workdays is None:
    workdays = [0, 1, 2, 3, 4]
else:
    workdays = workdays.split(",")

# check if we need to skip non workdays
if skip_non_workdays is False:
    workdays = [0, 1, 2, 3, 4, 5, 6]

# validate dates
if end < start:
    return False, "End date is before start date"

# now its time for us to iterate
i = start
while i <= end:

    # first let's give benefit of the doubt
    incr = True

    # lets see if day is in the workday array if not then fault it's existence here
    try:
        workdays.index(i.weekday())
    except ValueError:
        incr = False

    # lets check if day is an holiday, charge guilty if so.
    # We are checking the index in holiday array
    try:
        holidays.index(i)
        incr = False
    except (ValueError, AttributeError):
        pass

    if incr:
        duration += 1
        print "This day passed the criterion %s" % i

    i += timedelta(1)

return True, duration
于 2015-10-18T21:05:00.093 に答える