Dernière activité 10 months ago

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

timmy a révisé ce gist 10 months ago. Aller à la révision

Aucun changement

timmy a révisé ce gist 10 months ago. Aller à la révision

Aucun changement

timmy a révisé ce gist 11 months ago. Aller à la révision

Aucun changement

timmy a révisé ce gist 11 months ago. Aller à la révision

1 file changed, 44 insertions, 14 deletions

holiday_api_checker.py

@@ -1,20 +1,41 @@
1 1 import requests
2 + import os
3 + import json
2 4
3 5 class HolidayAPI:
4 - def __init__(self, base_url):
6 + def __init__(self, base_url, cache_dir="cache"):
5 7 """
6 8 Initialize the HolidayAPI class.
7 9 :param base_url: The base URL for the API endpoint.
10 + :param cache_dir: Directory to store cached data.
8 11 """
9 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")
10 26
11 27 def get_holidays(self, page=0, size=10):
12 28 """
13 - Fetch holiday data from the API.
29 + Fetch holiday data from the API or cache.
14 30 :param page: The page number to fetch.
15 31 :param size: The number of records per page.
16 32 :return: A list of holiday data dictionaries.
17 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 +
18 39 url = f"{self.base_url}?page={page}&size={size}"
19 40 headers = {
20 41 'accept': 'application/json'
@@ -22,16 +43,23 @@ class HolidayAPI:
22 43 response = requests.get(url, headers=headers)
23 44
24 45 if response.status_code == 200:
25 - return response.json()
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
26 50 else:
27 51 response.raise_for_status()
28 52
29 53 def get_holidays_by_year(self, year):
30 54 """
31 55 Fetch holiday data for a specific year.
56 + If the data is already cached, it returns from the cache.
32 57 :param year: The year for which to fetch holidays.
33 58 :return: A list of holiday data dictionaries for the given year.
34 59 """
60 + if year in self.cached_holidays:
61 + return self.cached_holidays[year]
62 +
35 63 all_holidays = []
36 64 page = 0
37 65 while True:
@@ -41,7 +69,12 @@ class HolidayAPI:
41 69 all_holidays.extend(data)
42 70 page += 1
43 71
44 - return [holiday for holiday in all_holidays if holiday.get("year") == str(year)]
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
45 78
46 79 def is_holiday(self, date):
47 80 """
@@ -49,15 +82,13 @@ class HolidayAPI:
49 82 :param date: The date to check in YYYYMMDD format.
50 83 :return: True if the date is a holiday, False otherwise.
51 84 """
52 - page = 0
53 - while True:
54 - data = self.get_holidays(page=page, size=100)
55 - if not data:
56 - break
57 - for holiday in data:
58 - if holiday.get("date") == date and holiday.get("isholiday") == "是":
59 - return True
60 - page += 1
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
61 92 return False
62 93
63 94 class Holiday:
@@ -104,7 +135,6 @@ if __name__ == "__main__":
104 135 print(holiday)
105 136
106 137 # Check if a specific date is a holiday
107 - # specific_date = "20250101"
108 138 specific_date = "20250102"
109 139 print(f"Is {specific_date} a holiday? {api.is_holiday(specific_date)}")
110 140

timmy a révisé ce gist 11 months ago. Aller à la révision

1 file changed, 110 insertions

holiday_api_checker.py(fichier créé)

@@ -0,0 +1,110 @@
1 + import requests
2 +
3 + class HolidayAPI:
4 + def __init__(self, base_url):
5 + """
6 + Initialize the HolidayAPI class.
7 + :param base_url: The base URL for the API endpoint.
8 + """
9 + self.base_url = base_url
10 +
11 + def get_holidays(self, page=0, size=10):
12 + """
13 + Fetch holiday data from the API.
14 + :param page: The page number to fetch.
15 + :param size: The number of records per page.
16 + :return: A list of holiday data dictionaries.
17 + """
18 + url = f"{self.base_url}?page={page}&size={size}"
19 + headers = {
20 + 'accept': 'application/json'
21 + }
22 + response = requests.get(url, headers=headers)
23 +
24 + if response.status_code == 200:
25 + return response.json()
26 + else:
27 + response.raise_for_status()
28 +
29 + def get_holidays_by_year(self, year):
30 + """
31 + Fetch holiday data for a specific year.
32 + :param year: The year for which to fetch holidays.
33 + :return: A list of holiday data dictionaries for the given year.
34 + """
35 + all_holidays = []
36 + page = 0
37 + while True:
38 + data = self.get_holidays(page=page, size=100)
39 + if not data:
40 + break
41 + all_holidays.extend(data)
42 + page += 1
43 +
44 + return [holiday for holiday in all_holidays if holiday.get("year") == str(year)]
45 +
46 + def is_holiday(self, date):
47 + """
48 + Check if a specific date is a holiday.
49 + :param date: The date to check in YYYYMMDD format.
50 + :return: True if the date is a holiday, False otherwise.
51 + """
52 + page = 0
53 + while True:
54 + data = self.get_holidays(page=page, size=100)
55 + if not data:
56 + break
57 + for holiday in data:
58 + if holiday.get("date") == date and holiday.get("isholiday") == "是":
59 + return True
60 + page += 1
61 + return False
62 +
63 + class Holiday:
64 + def __init__(self, date, year, name, isholiday, holidaycategory, description):
65 + """
66 + Represent a single holiday entry.
67 + :param date: The date of the holiday in YYYYMMDD format.
68 + :param year: The year of the holiday.
69 + :param name: The name of the holiday (if any).
70 + :param isholiday: Whether it is a holiday ('是' or '否').
71 + :param holidaycategory: The category of the holiday.
72 + :param description: The description of the holiday.
73 + """
74 + self.date = date
75 + self.year = year
76 + self.name = name
77 + self.isholiday = isholiday
78 + self.holidaycategory = holidaycategory
79 + self.description = description
80 +
81 + def __repr__(self):
82 + return f"Holiday(date={self.date}, year={self.year}, name={self.name}, " \
83 + f"isholiday={self.isholiday}, holidaycategory={self.holidaycategory}, " \
84 + f"description={self.description})"
85 +
86 + # Example usage
87 + if __name__ == "__main__":
88 + api = HolidayAPI("https://data.ntpc.gov.tw/api/datasets/308dcd75-6434-45bc-a95f-584da4fed251/json")
89 + holidays_2025 = api.get_holidays_by_year(2025)
90 +
91 + holidays = []
92 + for entry in holidays_2025:
93 + holiday = Holiday(
94 + date=entry.get("date"),
95 + year=entry.get("year"),
96 + name=entry.get("name"),
97 + isholiday=entry.get("isholiday"),
98 + holidaycategory=entry.get("holidaycategory"),
99 + description=entry.get("description")
100 + )
101 + holidays.append(holiday)
102 +
103 + for holiday in holidays:
104 + print(holiday)
105 +
106 + # Check if a specific date is a holiday
107 + # specific_date = "20250101"
108 + specific_date = "20250102"
109 + print(f"Is {specific_date} a holiday? {api.is_holiday(specific_date)}")
110 +
Plus récent Plus ancien