0

I've been diving into List Comprehensions, and I'm determined to put it into practice.

The below code takes a month and year input to determine the number of business days in the month, minus the public holidays (available at https://www.gov.uk/bank-holidays.json).

Additionally, I want to list all public holidays in that month/year, but I'm struck with a date format conflict.

TypeError: '<' not supported between instances of 'str' and 'datetime.date'

edate and sdate are datetime.date, whereas title["date"] is a string.

I've tried things like datetime.strptime and datetime.date to now avail.

How can I resolve the date conflict within the List Comprehension?

Any help or general feedback on code appreciated.

from datetime import date, timedelta, datetime
import inspect
from turtle import title
from typing import Iterator
import numpy as np
import json
import requests
from calendar import month, monthrange
import print

# Ask for a month and year input (set to September for quick testing)
monthInput = "09"
yearInput = "2022"

# Request from UK GOV and filter to England and Wales
holidaysJSON = requests.get("https://www.gov.uk/bank-holidays.json")
ukHolidaysJSON = json.loads(holidaysJSON.text)['england-and-wales']['events']

# List for all England and Wales holidays
ukHolidayList = []
eventIterator = 0
for events in ukHolidaysJSON:
    ukHolidayDate = list(ukHolidaysJSON[eventIterator].values())[1]
    ukHolidayList.append(ukHolidayDate)
    eventIterator += 1

# Calculate days in the month
daysInMonth = monthrange(int(yearInput), int(monthInput))[1] # Extract the number of days in the month

# Define start and end dates
sdate = date(int(yearInput), int(monthInput), 1)   # start date
edate = date(int(yearInput), int(monthInput), int(daysInMonth))   # end date

# Calculate delta
delta = edate - sdate

# Find all of the business days in the month
numberOfWorkingDays = 0
for i in range(delta.days + 1):  # Look through all days in the month
    day = sdate + timedelta(days=i)
    if np.is_busday([day]) and str(day) not in ukHolidayList: # Determine if it's a business day
        print("- " + str(day))
        numberOfWorkingDays += 1

# Count all of the UK holidays
numberOfHolidays = 0
for i in range(delta.days + 1):  # Look through all days in the month
    day = sdate + timedelta(days=i)
    if str(day) in ukHolidayList: # Determine if it's a uk holiday
        numberOfHolidays += 1

# Strip the 0 from the month input
month = months[monthInput.lstrip('0')]

# for x in ukHolidaysJSON:
#     pprint.pprint(x["title"])

# This is where I've gotten to
hols = [ title["title"] for title in ukHolidaysJSON if title["date"] < sdate and title["date"] > edate ]


print(hols)

1
  • Have you tried dateutil.parser? You could define a function like def asDate(dateStr): return duparser.parse(dateStr).date() [Don't forget to # import dateutil.parser as duparser first.] and then use asDate(title["date"]) in the comparisons with sdate and edate Commented Oct 2, 2022 at 21:47

2 Answers 2

1

I got this to work. You can used the datetime module to parse the string format but then you need to convert that result into a Date to compare to the Date objects you have already.

hols = [ title["title"] for title in ukHolidaysJSON if datetime.strptime(title["date"], '%Y-%m-%d').date() < sdate and datetime.strptime(title["date"], "%Y-%m-%d").date() > edate ]
Sign up to request clarification or add additional context in comments.

Comments

1

First use strptime and then convert the datetime object to date. I'm not sure if there's a more straightforward way but this seems to work:

hols = [title["title"] for title in ukHolidaysJSON
    if datetime.strptime(title["date"], "%Y-%M-%d").date() < sdate and
       datetime.strptime(title["date"], "%Y-%M-%d").date() > edate]

1 Comment

Thanks! That's very readable too.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.