Zuletzt aktiv 10 months ago

這段程式碼是一個節假日查詢工具,從指定 API 獲取節假日資料,支援緩存與分頁,並提供按年份篩選節假日、檢查特定日期是否為節假日的功能,同時以 Holiday 類別封裝每個節假日的詳細資訊,便於操作與顯示。

Änderung c24b0945f657b3429b192c9f08436dd1a1266f21

holiday_api_checker.py Originalformat
1import requests
2import os
3import json
4
5class HolidayAPI:
6 def __init__(self, base_url, cache_dir="cache"):
7 """
8 Initialize the HolidayAPI class.
9 :param base_url: The base URL for the API endpoint.
10 :param cache_dir: Directory to store cached data.
11 """
12 self.base_url = base_url
13 self.cached_holidays = {}
14 self.cache_dir = cache_dir
15 if not os.path.exists(self.cache_dir):
16 os.makedirs(self.cache_dir)
17
18 def _get_cache_path(self, page, size):
19 """
20 Generate the cache file path for a given page and size.
21 :param page: The page number.
22 :param size: The size of the page.
23 :return: Path to the cache file.
24 """
25 return os.path.join(self.cache_dir, f"holidays_page{page}_size{size}.json")
26
27 def get_holidays(self, page=0, size=10):
28 """
29 Fetch holiday data from the API or cache.
30 :param page: The page number to fetch.
31 :param size: The number of records per page.
32 :return: A list of holiday data dictionaries.
33 """
34 cache_path = self._get_cache_path(page, size)
35 if os.path.exists(cache_path):
36 with open(cache_path, "r", encoding="utf-8") as cache_file:
37 return json.load(cache_file)
38
39 url = f"{self.base_url}?page={page}&size={size}"
40 headers = {
41 'accept': 'application/json'
42 }
43 response = requests.get(url, headers=headers)
44
45 if response.status_code == 200:
46 data = response.json()
47 with open(cache_path, "w", encoding="utf-8") as cache_file:
48 json.dump(data, cache_file, ensure_ascii=False, indent=4)
49 return data
50 else:
51 response.raise_for_status()
52
53 def get_holidays_by_year(self, year):
54 """
55 Fetch holiday data for a specific year.
56 If the data is already cached, it returns from the cache.
57 :param year: The year for which to fetch holidays.
58 :return: A list of holiday data dictionaries for the given year.
59 """
60 if year in self.cached_holidays:
61 return self.cached_holidays[year]
62
63 all_holidays = []
64 page = 0
65 while True:
66 data = self.get_holidays(page=page, size=100)
67 if not data:
68 break
69 all_holidays.extend(data)
70 page += 1
71
72 filtered_holidays = [
73 holiday for holiday in all_holidays
74 if holiday.get("year") == str(year) and holiday.get("date")[4:] != "0903"
75 ]
76 self.cached_holidays[year] = filtered_holidays
77 return filtered_holidays
78
79 def is_holiday(self, date):
80 """
81 Check if a specific date is a holiday.
82 :param date: The date to check in YYYYMMDD format.
83 :return: True if the date is a holiday, False otherwise.
84 """
85 year = date[:4]
86 if year not in self.cached_holidays:
87 self.get_holidays_by_year(year)
88
89 for holiday in self.cached_holidays[year]:
90 if holiday.get("date") == date and holiday.get("isholiday") == "":
91 return True
92 return False
93
94class Holiday:
95 def __init__(self, date, year, name, isholiday, holidaycategory, description):
96 """
97 Represent a single holiday entry.
98 :param date: The date of the holiday in YYYYMMDD format.
99 :param year: The year of the holiday.
100 :param name: The name of the holiday (if any).
101 :param isholiday: Whether it is a holiday ('' or '').
102 :param holidaycategory: The category of the holiday.
103 :param description: The description of the holiday.
104 """
105 self.date = date
106 self.year = year
107 self.name = name
108 self.isholiday = isholiday
109 self.holidaycategory = holidaycategory
110 self.description = description
111
112 def __repr__(self):
113 return f"Holiday(date={self.date}, year={self.year}, name={self.name}, " \
114 f"isholiday={self.isholiday}, holidaycategory={self.holidaycategory}, " \
115 f"description={self.description})"
116
117# Example usage
118if __name__ == "__main__":
119 api = HolidayAPI("https://data.ntpc.gov.tw/api/datasets/308dcd75-6434-45bc-a95f-584da4fed251/json")
120 holidays_2025 = api.get_holidays_by_year(2025)
121
122 holidays = []
123 for entry in holidays_2025:
124 holiday = Holiday(
125 date=entry.get("date"),
126 year=entry.get("year"),
127 name=entry.get("name"),
128 isholiday=entry.get("isholiday"),
129 holidaycategory=entry.get("holidaycategory"),
130 description=entry.get("description")
131 )
132 holidays.append(holiday)
133
134 for holiday in holidays:
135 print(holiday)
136
137 # Check if a specific date is a holiday
138 specific_date = "20250102"
139 print(f"Is {specific_date} a holiday? {api.is_holiday(specific_date)}")
140
141