List iteration through JSON array with dates (date format conflict)

Question:

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)

Asked By: Steven Diffey

||

Answers:

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]
Answered By: StreakyFly

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 ]
Answered By: Sobigen
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.