2012-07-18 14 views
8

मैं व्यावसायिक दिनों (सप्ताह के दिनों) में पुनरावृत्ति करने के लिए जेनरेटर फ़ंक्शन बनाने की कोशिश कर रहा हूं, सप्ताहांत छोड़ना (और छुट्टियां भी अच्छी होंगी!)।व्यवसाय दिवसों पर पाइथन तिथि सीमा जनरेटर

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

मैं जनरेटर सप्ताहांत और छुट्टियों छोड़ बनाने के लिए एक स्वच्छ, कुशल, और pythonic तरीका यह पता लगाने के लिए संघर्ष कर रही है: अब तक, मैं केवल एक समारोह दिनों में कि बस दोहराता है। अग्रिम में धन्यवाद!

+1

छुट्टियों के लिए इस सवाल का देखें: http://stackoverflow.com/questions/1986207/holiday-calendars-file -formats-et-al –

उत्तर

23

पर मैं मजबूत इस तरह के कार्यों के लिए 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)) 
+0

अच्छा उदाहरण! +1 –

+0

क्या यह वास्तव में आप क्या कहते हैं? मैंने लिनक्स और मैक ओएस पर पायथन 2.7 और 3.3 पर कोशिश की, और सभी मामलों में यह सप्ताहांत सहित सभी दिन लौटाता है। यदि आप 'dateutil.rrule.WDAYMASK' देखते हैं तो आप देख सकते हैं कि यह 0-6 की सूची है, यानी सभी दिन, न केवल सोमवार-शुक्रवार। –

+0

@ जोहानज़विनक राइट, WDAYMASK वास्तव में गलत है (कम से कम डेट्यूटिल के मौजूदा संस्करणों के साथ)। मैंने इसे प्रतिबिंबित करने के लिए उत्तर अपडेट किया। – earl

6

मान लिया जाये कि startDate और endDate दिनांक या दिनांक वस्तुओं रहे हैं, तो आप उपयोग कर सकते हैं the weekday method सप्ताह के दिन पाने के लिए है, तो इसे छोड़ अगर यह शनिवार या रविवार है। बस कार्य करें:

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) 

छुट्टियों के लिए आप प्रत्येक छुट्टी आप चाहते हैं के लिए मैन्युअल रूप से जाँच करने के लिए होगा। कुछ छुट्टियों को जटिल तरीकों से परिभाषित किया जाता है, इसलिए यह थोड़ा मुश्किल हो सकता है।

7

dateutil नामक एक उपयोगी लाइब्रेरी है जो आपके लिए इस तरह की चीज कर सकती है। यह कुछ दिनों को छोड़कर, तारीखों की सीमाओं (या कस्टम नियमों के आधार पर तिथियां) उत्पन्न कर सकता है, एक दिन आदि से शुरू होने वाले सप्ताह पर विचार करें ... बिल्टिन डेटाटाइम लाइब्रेरी की तुलना में कुछ और अधिक लचीला टाइमडेल्टा भी है। http://labix.org/python-dateutil/ पर

डॉक्स - और उपलब्ध PyPi

0
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 
संबंधित मुद्दे