Joe Smart
Joe Smart

Reputation: 763

Incrementing date whilst ignoring weekends

I am currently writing a support rota for my workplace.

The code itself is simple

import itertools

names = ["P1", "P2", "P3"]

extns = {'P1': 'xxxx', 'P2': 'xxxy', 'P3': 'xxyy'}

for _ in itertools.repeat(None, 5):
    for name in names:
        print name + " | " + extns[name]

(Names replaced with Pn and numbers replaced with "x/y" substitutes)

This works great so far and gives me the expected output of

P1 | xxxx
P2 | xxxy
P3 | xxyy

repeated 5 times.

However the desired output is

| <Todays Date> | P1 | xxxx |

Obviously I could just use a calendar Lib and use the data from there and then just do something such a today+1 for tomorrow's date etc.

The problem occurs when trying to skip weekend.

Working a 5 day week means we do not allocate support on weekends (Saturday/Sunday 0000-2400)

For example for September the 1st was a monday so I would want the dates to be

01-09-14
02-09-14
03-09-14
04-09-14
05-09-14
08-09-14
09-09-14

As you can see it skips the 6th and 7th as that is a saturday and sunday.

I have looked at the calendar module and found code for:

calendar.setfirstday()

Which sounds promising, I can also use

iterweekdays()

to return and iterator for weekdays.

I'm not sure though whether this would give dates if I were to iterate through it. I am also unsure how I would actually iterate through it.

EDIT:

Below is expected output:

| 10-09-14 | P1 | xxxx | 
| 11-09-14 | P2 | xxxy | 
| 12-09-14 | P3 | xxyy | 
| 15-09-14 | P1 | xxxx | 
| 16-09-14 | P2 | xxxy | 
| 17-09-14 | P3 | xxyy | 
| 18-09-14 | P1 | xxxx |  
| 19-09-14 | P2 | xxxy | 
| 22-09-14 | P3 | xxxy | 
| 23-09-14 | P1 | xxxx | 
| 24-09-14 | P2 | xxxy | 
| 25-09-14 | P3 | xxyy | 
| 26-09-14 | P1 | xxxx | 
| 29-09-14 | P2 | xxxy | 
| 30-09-14 | P3 | xxyy | 

Currently I can get todays date and check whether or not it is a weekday. The problem then is going ahead in time.

Upvotes: 2

Views: 2014

Answers (4)

PM 2Ring
PM 2Ring

Reputation: 55469

This might give you some ideas.

#! /usr/bin/env python

'''
A generator that returns the dates of consecutive days, skipping weekends
'''

import sys
import datetime

def weekday_gen(current_date):
    day_delta = datetime.timedelta(1)
    while True:
        if current_date.weekday() < 5: 
            yield current_date
        current_date += day_delta


def main():
    if len(sys.argv) > 3:
        d, m, y = [int(s) for s in sys.argv[1:4]]
        start_date = datetime.date(y, m, d)
    else:
        start_date = datetime.date.today()

    weekdays = weekday_gen(start_date)
    for i in xrange(30):
        day = weekdays.next()
        print day, day.strftime('%A')


if __name__ == '__main__':
    main()

But what do you do about public holidays...

Upvotes: 0

user3960432
user3960432

Reputation:

This should do the trick:

import itertools
from datetime import datetime, timedelta

names = ["P1", "P2", "P3"]
extns = {'P1': 'xxxx', 'P2': 'xxxy', 'P3': 'xxyy'}

for (day,name) in itertools.izip((day for day in (datetime.today()+timedelta(n) for n in itertools.count()) if day.weekday() not in (5,6)), (itertools.cycle(names))):
    print "| %s | %s | %s |" % (day.strftime("%d-%m-%y"), name, extns[name])

Starts the count from today and loops indefinitely. I only assume that's what you desired as that's how your original code as structured. If you want it for specific time frames only let me know.


EDIT: As per comments, this should print out only today + 10 days. This could probably be done numerous ways but this way you can easily edit how many days you want even down to just today:

import itertools
from datetime import datetime, timedelta

names = ["P1", "P2", "P3"]
extns = {'P1': 'xxxx', 'P2': 'xxxy', 'P3': 'xxyy'}
days = 11

for (day,name) in itertools.izip((day for day in (datetime.today()+timedelta(n) for n in itertools.count()) if day.weekday() not in (5,6)), (itertools.cycle(names))):    
    if days == 0:
        break

    print "| %s | %s | %s |" % (day.strftime("%d-%m-%Y"), name, extns[name])
    days-= 1

Upvotes: 1

venpa
venpa

Reputation: 4318

you could use weekday of calendar, if that returns 5 or 6, you can consider as weekend.

EDIT: You could do following with datetime:

>>> import datetime
>>> d=datetime.date(2014,9,10)
>>> d.weekday()
2

Upvotes: 2

xoryouyou
xoryouyou

Reputation: 656

You can simply use datetime and its .weekday() function which maps the days of a week to 0-6 beginning with monday = 0 and ending with sunday = 6.

from datetime import datetime

today = datetime.today()  # get todays datetime

if not today.weekday() == 5 or today.weekday == 6:   # if we no weekend-day

    print(datetime.strftime(today,'%d-%m-%y')) # format it to day-month-year

Upvotes: 3

Related Questions