mirror of
https://github.com/muhac/chinese-holidays-calendar.git
synced 2024-11-21 01:01:50 +08:00
Add Ontario holiday
testing ip
This commit is contained in:
parent
94584e0835
commit
4776475589
18
.github/workflows/cd.yml
vendored
18
.github/workflows/cd.yml
vendored
@ -32,6 +32,14 @@ jobs:
|
|||||||
shell: bash
|
shell: bash
|
||||||
run: python crawler.py
|
run: python crawler.py
|
||||||
|
|
||||||
|
- name: Run global scripts
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
for script in global/*/main.py; do
|
||||||
|
cd $(dirname $script)
|
||||||
|
python $(basename $script)
|
||||||
|
done
|
||||||
|
|
||||||
- name: Setup Haskell and Cabal
|
- name: Setup Haskell and Cabal
|
||||||
uses: haskell-actions/setup@v2
|
uses: haskell-actions/setup@v2
|
||||||
with:
|
with:
|
||||||
@ -44,10 +52,18 @@ jobs:
|
|||||||
- name: Generate ICS files
|
- name: Generate ICS files
|
||||||
run: cabal run
|
run: cabal run
|
||||||
|
|
||||||
|
- name: Generate global data
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
for script in global/*/deploy.sh; do
|
||||||
|
cd $(dirname $script)
|
||||||
|
bash $(basename $script) 2>/dev/null
|
||||||
|
done
|
||||||
|
|
||||||
- name: Commit changes
|
- name: Commit changes
|
||||||
uses: stefanzweifel/git-auto-commit-action@v5
|
uses: stefanzweifel/git-auto-commit-action@v5
|
||||||
with:
|
with:
|
||||||
file_pattern: README.md docs/* data/*
|
file_pattern: README.md data/* global/*/data/* docs/* docs/global/*/*
|
||||||
commit_message: update calendar data automatically
|
commit_message: update calendar data automatically
|
||||||
commit_user_name: Muhan Li
|
commit_user_name: Muhan Li
|
||||||
commit_user_email: 77625954+muhav@users.noreply.github.com
|
commit_user_email: 77625954+muhav@users.noreply.github.com
|
||||||
|
8
.github/workflows/ci.yml
vendored
8
.github/workflows/ci.yml
vendored
@ -33,6 +33,14 @@ jobs:
|
|||||||
shell: bash
|
shell: bash
|
||||||
run: python crawler.py
|
run: python crawler.py
|
||||||
|
|
||||||
|
- name: Run global scripts
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
for script in global/*/main.py; do
|
||||||
|
cd $(dirname $script)
|
||||||
|
python $(basename $script)
|
||||||
|
done
|
||||||
|
|
||||||
parser:
|
parser:
|
||||||
name: Parser Dry Run
|
name: Parser Dry Run
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
12
global/ca_on/data/2022.txt
Normal file
12
global/ca_on/data/2022.txt
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
// Ontario Public Holidays in 2022
|
||||||
|
// I hope ChatGPT gets the dates correct
|
||||||
|
|
||||||
|
元旦_New_Year's_Day;2022.1.3;2022.1.1-2022.1.3
|
||||||
|
家庭日_Family_Day;2022.2.21;2022.2.19-2022.2.21
|
||||||
|
耶稣受难日_Good_Friday;2022.4.15;2022.4.15-2022.4.17
|
||||||
|
维多利亚日_Victoria_Day;2022.5.23;2022.5.21-2022.5.23
|
||||||
|
国庆节_Canada_Day;2022.7.1;2022.7.1-2022.7.3
|
||||||
|
劳动节_Labour_Day;2022.9.5;2022.9.3-2022.9.5
|
||||||
|
感恩节_Thanksgiving;2022.10.10;2022.10.8-2022.10.10
|
||||||
|
圣诞节_Christmas_Day;2022.12.26;2022.12.24-2022.12.27
|
||||||
|
节礼日_Boxing_Day;2022.12.27;
|
12
global/ca_on/data/2023.txt
Normal file
12
global/ca_on/data/2023.txt
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
// Ontario Public Holidays in 2023
|
||||||
|
// I hope ChatGPT gets the dates correct
|
||||||
|
|
||||||
|
元旦_New_Year's_Day;2023.1.2;2022.12.31-2023.1.2
|
||||||
|
家庭日_Family_Day;2023.2.20;2023.2.18-2023.2.20
|
||||||
|
耶稣受难日_Good_Friday;2023.4.7;2023.4.7-2023.4.9
|
||||||
|
维多利亚日_Victoria_Day;2023.5.22;2023.5.20-2023.5.22
|
||||||
|
国庆节_Canada_Day;2023.7.3;2023.7.1-2023.7.3
|
||||||
|
劳动节_Labour_Day;2023.9.4;2023.9.2-2023.9.4
|
||||||
|
感恩节_Thanksgiving;2023.10.9;2023.10.7-2023.10.9
|
||||||
|
圣诞节_Christmas_Day;2023.12.25;2023.12.23-2023.12.26
|
||||||
|
节礼日_Boxing_Day;2023.12.26;
|
12
global/ca_on/data/2024.txt
Normal file
12
global/ca_on/data/2024.txt
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
// Ontario Public Holidays in 2024
|
||||||
|
// I hope ChatGPT gets the dates correct
|
||||||
|
|
||||||
|
元旦_New_Year's_Day;2024.1.1;2023.12.30-2024.1.1
|
||||||
|
家庭日_Family_Day;2024.2.19;2024.2.17-2024.2.19
|
||||||
|
耶稣受难日_Good_Friday;2024.3.29;2024.3.29-2024.3.31
|
||||||
|
维多利亚日_Victoria_Day;2024.5.20;2024.5.18-2024.5.20
|
||||||
|
国庆节_Canada_Day;2024.7.1;2024.6.29-2024.7.1
|
||||||
|
劳动节_Labour_Day;2024.9.2;2024.8.31-2024.9.2
|
||||||
|
感恩节_Thanksgiving;2024.10.14;2024.10.12-2024.10.14
|
||||||
|
圣诞节_Christmas_Day;2024.12.25;2024.12.25-2024.12.26
|
||||||
|
节礼日_Boxing_Day;2024.12.26;
|
23
global/ca_on/deploy.sh
Normal file
23
global/ca_on/deploy.sh
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
# To make it simple, copy the parser script
|
||||||
|
# to the current directory, and I only need
|
||||||
|
# to modify the titles of the output files.
|
||||||
|
mkdir docs
|
||||||
|
mkdir -p ../../docs/global/ca_on
|
||||||
|
|
||||||
|
cp -r ../../parser.cabal .
|
||||||
|
cp -r ../../parser .
|
||||||
|
|
||||||
|
sed -i \
|
||||||
|
-e 's/Chinese Holidays/Ontario Statutory Holidays/' \
|
||||||
|
-e 's/titleStatus status/"加拿大安大略省公共假日"/' \
|
||||||
|
-e 's/name ++ show status/unwords name_en/' \
|
||||||
|
-e 's/show status/name_cn ++ " "/' \
|
||||||
|
-e 's/0xa95511fe/0xca4ada04;name_cn:name_en=splitOn "_" name/' \
|
||||||
|
-e 's/import/import Data.List.Split (splitOn);import/' \
|
||||||
|
./parser/Main/Output.hs
|
||||||
|
|
||||||
|
cabal build
|
||||||
|
cabal run
|
||||||
|
|
||||||
|
mv docs/rest.ics ../../docs/global/ca_on/main.ics
|
||||||
|
mv docs/work.ics ../../docs/global/ca_on/rest.ics
|
166
global/ca_on/main.py
Normal file
166
global/ca_on/main.py
Normal file
@ -0,0 +1,166 @@
|
|||||||
|
"""
|
||||||
|
Generate the public holidays in Ontario for the next year
|
||||||
|
Thanks to ChatGPT and Copilot for the code
|
||||||
|
"""
|
||||||
|
|
||||||
|
import datetime
|
||||||
|
from dateutil.easter import easter
|
||||||
|
|
||||||
|
|
||||||
|
class Holiday:
|
||||||
|
"""节假日"""
|
||||||
|
|
||||||
|
def __init__(self, name_cn, name_en, date):
|
||||||
|
self.name_cn = name_cn
|
||||||
|
self.name_en = name_en
|
||||||
|
self.date = date
|
||||||
|
self.long_weekend_dates = None
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
"""格式化 debug 输出"""
|
||||||
|
return f"{self.name_cn}: {self.format_date(self.date)}"
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def format_date(date):
|
||||||
|
"""格式化日期为 data.txt 的格式"""
|
||||||
|
return date.strftime('%Y.%-m.%-d')
|
||||||
|
|
||||||
|
|
||||||
|
def get_holidays(year: int) -> list[Holiday]:
|
||||||
|
"""获取给定年份的节假日"""
|
||||||
|
holidays = [
|
||||||
|
# 固定假日
|
||||||
|
# 元旦 (1月1日)
|
||||||
|
Holiday("元旦", "New Year's Day", datetime.date(year, 1, 1)),
|
||||||
|
# 劳动节 (5月1日)
|
||||||
|
Holiday("国庆节", "Canada Day", datetime.date(year, 7, 1)),
|
||||||
|
# 圣诞节 (12月25日)
|
||||||
|
Holiday("圣诞节", "Christmas Day", datetime.date(year, 12, 25)),
|
||||||
|
# 节礼日 (12月26日)
|
||||||
|
Holiday("节礼日", "Boxing Day", datetime.date(year, 12, 26)),
|
||||||
|
|
||||||
|
# 变动假日
|
||||||
|
# 耶稣受难日(复活节前2天)
|
||||||
|
Holiday("耶稣受难日", "Good Friday", easter(year) - datetime.timedelta(days=2)),
|
||||||
|
# 维多利亚日(5月最后一个周一)
|
||||||
|
Holiday("维多利亚日", "Victoria Day", get_last_monday(datetime.date(year, 5, 25))),
|
||||||
|
# 劳动节(9月的第一个周一)
|
||||||
|
Holiday("劳动节", "Labour Day", get_first_monday(datetime.date(year, 9, 1))),
|
||||||
|
# 感恩节(10月的第二个周一)
|
||||||
|
Holiday("感恩节", "Thanksgiving", get_second_monday(datetime.date(year, 10, 1))),
|
||||||
|
# 家庭日(2月的第三个周一)
|
||||||
|
Holiday("家庭日", "Family Day", get_third_monday(datetime.date(year, 2, 1))),
|
||||||
|
]
|
||||||
|
|
||||||
|
# 处理假日如果落在周末的情况
|
||||||
|
adjust_for_weekends(holidays)
|
||||||
|
connect_long_weekends(holidays)
|
||||||
|
|
||||||
|
return holidays
|
||||||
|
|
||||||
|
|
||||||
|
def get_first_monday(date):
|
||||||
|
"""获取给定日期所在月的第一个星期一"""
|
||||||
|
while date.weekday() != 0:
|
||||||
|
date += datetime.timedelta(days=1)
|
||||||
|
return date
|
||||||
|
|
||||||
|
|
||||||
|
def get_second_monday(date):
|
||||||
|
"""获取给定日期所在月的第二个星期一"""
|
||||||
|
first_monday = get_first_monday(date)
|
||||||
|
return first_monday + datetime.timedelta(days=7)
|
||||||
|
|
||||||
|
|
||||||
|
def get_third_monday(date):
|
||||||
|
"""获取给定日期所在月的第三个星期一"""
|
||||||
|
first_monday = get_first_monday(date)
|
||||||
|
return first_monday + datetime.timedelta(days=14)
|
||||||
|
|
||||||
|
|
||||||
|
def get_last_monday(date):
|
||||||
|
"""获取给定日期所在月的最后一个星期一"""
|
||||||
|
while date.weekday() != 0:
|
||||||
|
date -= datetime.timedelta(days=1)
|
||||||
|
return date
|
||||||
|
|
||||||
|
|
||||||
|
def adjust_for_weekends(holidays: list[Holiday]):
|
||||||
|
"""如果假日落在周末,将假日顺延到下一个工作日,特殊处理圣诞节和节礼日"""
|
||||||
|
boxing_day_delta = 0
|
||||||
|
for holiday in holidays:
|
||||||
|
# 特殊处理圣诞节和节礼日
|
||||||
|
if holiday.name_cn == "圣诞节" and holiday.date.weekday() == 5:
|
||||||
|
# 圣诞节在周六, 节礼日在周日
|
||||||
|
holiday.date += datetime.timedelta(days=2)
|
||||||
|
boxing_day_delta = 2
|
||||||
|
elif holiday.name_cn == "圣诞节" and holiday.date.weekday() == 6:
|
||||||
|
# 圣诞节在周日, 节礼日在周一
|
||||||
|
holiday.date += datetime.timedelta(days=1)
|
||||||
|
boxing_day_delta = 1
|
||||||
|
elif holiday.name_cn == "节礼日" and holiday.date.weekday() == 5:
|
||||||
|
# 节礼日在周六
|
||||||
|
holiday.date += datetime.timedelta(days=2)
|
||||||
|
elif holiday.name_cn == "节礼日":
|
||||||
|
holiday.date += datetime.timedelta(days=boxing_day_delta)
|
||||||
|
else:
|
||||||
|
# 其他假期处理
|
||||||
|
if holiday.date.weekday() == 5: # 如果是假日落在周六
|
||||||
|
holiday.date += datetime.timedelta(days=2)
|
||||||
|
elif holiday.date.weekday() == 6: # 如果是假日落在周日
|
||||||
|
holiday.date += datetime.timedelta(days=1)
|
||||||
|
|
||||||
|
|
||||||
|
def connect_long_weekends(holidays: list[Holiday]):
|
||||||
|
"""将连续的假期连接起来"""
|
||||||
|
boxing_day = next(h.date for h in holidays if h.name_cn == "节礼日")
|
||||||
|
|
||||||
|
for holiday in holidays:
|
||||||
|
dates = [holiday.date]
|
||||||
|
if holiday.name_cn == "节礼日":
|
||||||
|
continue
|
||||||
|
if holiday.name_cn == "圣诞节":
|
||||||
|
dates.append(boxing_day)
|
||||||
|
|
||||||
|
long_weekend_start = holiday.date
|
||||||
|
while is_weekend(prev_day := long_weekend_start - datetime.timedelta(days=1), dates):
|
||||||
|
long_weekend_start = prev_day
|
||||||
|
|
||||||
|
long_weekend_end = holiday.date
|
||||||
|
while is_weekend(next_day := long_weekend_end + datetime.timedelta(days=1), dates):
|
||||||
|
long_weekend_end = next_day
|
||||||
|
|
||||||
|
holiday.long_weekend_dates = (
|
||||||
|
Holiday.format_date(long_weekend_start),
|
||||||
|
Holiday.format_date(long_weekend_end),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def is_weekend(date, extra_holidays=None):
|
||||||
|
"""判断给定日期是否是周末或者公共假日"""
|
||||||
|
return date.weekday() >= 5 or (extra_holidays and date in extra_holidays)
|
||||||
|
|
||||||
|
|
||||||
|
def main(year=None):
|
||||||
|
"""生成下一年的节假日数据"""
|
||||||
|
next_year = year if year else datetime.datetime.now().year + 1
|
||||||
|
print(f"Generating Ontario holidays for {next_year}")
|
||||||
|
|
||||||
|
holidays = get_holidays(next_year)
|
||||||
|
holidays.sort(key=lambda x: x.date)
|
||||||
|
|
||||||
|
data = (f"// Ontario Public Holidays in {next_year}\n"
|
||||||
|
f"// I hope ChatGPT gets the dates correct\n\n")
|
||||||
|
|
||||||
|
for holiday in holidays:
|
||||||
|
print(holiday)
|
||||||
|
title = f"{holiday.name_cn} {holiday.name_en}".replace(' ', '_')
|
||||||
|
data += (f"{title};{Holiday.format_date(holiday.date)};"
|
||||||
|
f"{f'{d[0]}-{d[1]}' if (d := holiday.long_weekend_dates) else ''}\n") # pylint: disable=unsubscriptable-object
|
||||||
|
|
||||||
|
with open(f"./data/{next_year}.txt", "w", encoding='utf-8') as f:
|
||||||
|
f.write(data)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
@ -1 +1,2 @@
|
|||||||
requests~=2.28.1
|
requests~=2.32.3
|
||||||
|
python-dateutil~=2.9.0
|
||||||
|
Loading…
Reference in New Issue
Block a user