nager / Nager.Date

Worldwide holidays (REST API), NuGet or docker container :earth_americas:
https://date.nager.at
MIT License
1.06k stars 171 forks source link

ZA South Africa Election Day - 29 May 2024 Missing. #641

Closed BenPy007 closed 2 months ago

BenPy007 commented 2 months ago

Affected country

South Africa

Affected public holiday

Election Day

Source of the information

https://www.gov.za/news/elections2024

More information

Can we add the 2024 South Africa (ZA) Elections public holiday please :-)

BenPy007 commented 2 months ago

https://www.msn.com/en-us/news/other/public-holidays-two-coming-up-in-may/ar-AA1nA91d

tinohager commented 2 months ago

The new version is now available

BenPy007 commented 2 months ago

@tinohager Thanks so much, I see the update in V2 of the API but V3 seems to drop it? I see V2 will be deprecated at the end of the year so just wanted to flag. Will reference V2 for the moment. Thanks so much! Ben

tinohager commented 2 months ago

https://date.nager.at/api/v3/PublicHolidays/2024/ZA

image

BenPy007 commented 2 months ago

Sorry to be playing comment tennis @tinohager :-) If you click on https://date.nager.at/api/v3/PublicHolidays/2024/ZA it is not included or I just cannot see it, and neither does my API request pick it up. Attached a screenshot.

Owe you a coffee.

Not found1

tinohager commented 2 months ago

maybe your query is cached?

BenPy007 commented 2 months ago

You would be so proud of me if my query is cached! :-) I see it in V2 fine, but will try and see, good point! See it in V2 no problem.

Included V2

BenPy007 commented 2 months ago

Ok, think I worked it out. The server was serving me cached data, you were right. Included a timestamp into my python query to force it to bypass caching.

Here it is incase it can be useful to anyone:

import requests import pandas as pd from datetime import datetime import os

def fetch_holidays(year, country_code): """Fetch holidays for a given year and country using the Nager.Date API.""" timestamp = datetime.utcnow().strftime('%Y%m%d%H%M%S%f')[:-3] url = f"https://date.nager.at/api/v3/publicholidays/{year}/{country_code}?timestamp={timestamp}" response = requests.get(url) if response.status_code == 200: holidays = response.json()

Ensure each holiday has a 'date' key

    return [holiday for holiday in holidays if 'date' in holiday]
else:
    print(f"Failed to fetch data for {year}: {response.status_code}")
    return []

def save_holidays_to_excel(start_year, end_year, country_code, filename): """Fetch holidays for multiple years and save them in an Excel file.""" all_holidays = [] for year in range(start_year, end_year + 1): holidays = fetch_holidays(year, country_code) for holiday in holidays: holiday['Year'] = year # Add the year to the holiday dictionary all_holidays.append(holiday)

# Convert the list of holidays to a DataFrame
df = pd.DataFrame(all_holidays)
if 'date' in df.columns:
    df['date'] = pd.to_datetime(df['date']).dt.date  # Convert to date, removing time
    df.rename(columns={'date': 'Date'}, inplace=True)
else:
    print("Date column not found in the data")

# Get the directory of the current script
current_dir = os.path.dirname(os.path.realpath(__file__))
full_path = os.path.join(current_dir, filename)

# Save the DataFrame to an Excel file
with pd.ExcelWriter(full_path, engine='openpyxl', date_format='yyyy-mm-dd') as writer:
    df.to_excel(writer, index=False)

print(f"Saved holidays from {start_year} to {end_year} to {full_path}")

Example usage

save_holidays_to_excel(2023, 2025, 'ZA', 'holidays.xlsx')

tinohager commented 2 months ago

I think the cache was only active in your browser, you shouldn't call the api like that so you prevent a meaningful caching on our side