-1

I have the following day types:

daytypes = {
    'Holidays_1': (
        date(2017, 4, 20),
        date(2017, 7, 10)
    ),
    'Holidays_2': (
        date(2017, 2, 5),
        date(2017, 5, 12),
        date(2017, 12, 14)
    )
}

I want to know if the new date is a labour day (Monday-Friday) that is located 1 day before any holiday, and it is not a holiday itself.

For example, I have the following three datetime variables:

from datetime import datetime
dt1 = datetime.strptime("2017-02-04 11:12:20.0", "%Y-%m-%d %H:%M:%S.%f")
dt2 = datetime.strptime("2017-05-11 20:00:00.0", "%Y-%m-%d %H:%M:%S.%f")
dt3 = datetime.strptime("2017-02-06 12:00:00.0", "%Y-%m-%d %H:%M:%S.%f")

Only dt2 corresponds to the specified rule.

How can I do this?

Dinosaurius
  • 8,306
  • 19
  • 64
  • 113

4 Answers4

1

try this

from datetime import datetime as date
from datetime import timedelta, datetime

daytypes = {
    'Holidays_1': (
        date(2017, 4, 20),
        date(2017, 7, 10)
    ),
    'Holidays_2': (
        date(2017, 2, 5),
        date(2017, 5, 12),
        date(2017, 12, 14)
    )
}

holidays = []
for d in daytypes:
    holidays.extend(daytypes[d])

dt2 = datetime.strptime("2017-05-11 20:00:00.0", "%Y-%m-%d %H:%M:%S.%f")

for h in holidays:
    if h-dt2 < timedelta(1) and h-dt2 > timedelta(0):
        return True
binu.py
  • 1,137
  • 2
  • 9
  • 20
1

You can use the weekday() function to get what day of the week is your date object. The function returns an integer from 0 (monday) to 6 (sunday).

For example:

>>> from datetime import datetime, date
>>> dt1 = datetime.strptime("2017-02-04 11:12:20.0", "%Y-%m-%d %H:%M:%S.%f")
>>> holiday1 = date(2017, 02, 05)
>>> # Is the holiday one day ahead of the date?
>>> print date(dt1.year, dt1.month, dt1.day + 1) == holiday1 
True
>>> # Is the date a weekday?
>>> print dt1.weekday() in range(0,4) # Days from 0 to 4 are working days
False

Documentation is here: https://docs.python.org/2/library/datetime.html#datetime.date.weekday

Edit: You can use a for loop to iterate over each of your holidays:

for holiday_tuple in daytypes.keys():
    for holiday in holiday_tuple:
        # Do whatever you need here
        print date(dtx.year, dtx.month, dtx.day + 1) == holiday

Where dtx is any of the declared datetime objects. You could also use an additionnal for loop to iterate over a list of datetime objects.

MDL
  • 107
  • 1
  • 10
0

Here is a quick function to accomplish this. The function takes your dictionary of holidays and will evaluate the input date against those holidays and will return whether the input date is a weekend, within 1 day of a holiday, or a weekday not within one day of a holiday. You can change the functions to return more or less detail if needed, but this should fit the needs you describe.

def check_holidays(holidays, input_date):
    if input_date.weekday() >= 5:
        return 'Is a weekend date'
    for holiday, holiday_dates in holidays.items():
        holiday_range = []
        for h_date in holiday_dates:
            holiday_range.append(h_date)
            holiday_range.append(h_date - timedelta(days=1))
        if input_date.date() in holiday_range:
            return 'Date is within 1 day of a holiday'
    return 'Date is a weekday and not within 1 day of a holiday'
vielkind
  • 2,840
  • 1
  • 16
  • 16
  • I get this error `AttributeError: type object 'datetime.datetime' has no attribute 'timedelta'`, when I run `check_holidays(daytypes,dt2)` – Dinosaurius Aug 08 '17 at 15:14
  • I see. Since you're doing `from datetime import datetime` you should add `timedelta` to your import to read `from datetime import datetime, timedelta`. Then you can drop `datetime` from the function and call `timedelta` directly. I've updated the code to show this. – vielkind Aug 08 '17 at 15:17
  • Hmm, it gives me now `Date is a weekday and not within 1 day of a holiday` for all entries. – Dinosaurius Aug 08 '17 at 15:22
0

I solved it this way:

holidays = []
for d in daytypes:
    holidays.extend(daytypes[d])

if (dt.isoweekday() >= 1 and dt.isoweekday() <= 5 and date(dt.year, dt.month, dt.day + 1) in holidays):
    print "Date is within 1 day of a holiday."
else:
    print "Date is a weekday and not within 1 day of a holiday."
Dinosaurius
  • 8,306
  • 19
  • 64
  • 113