將臺北市、新北市政府開放資料平台的「辦公日曆表」轉換成每年一份、全年逐日的 JSON,方便程式判斷某一天政府行政機關是否上班。
臺灣行政院人事行政總處每年上半年公告來年辦公日曆表,但僅以文件、圖檔呈現,不利程式介接。本專案以下列兩個結構化來源為基礎自動產出 JSON。
| 代碼 | 機關 | 開放資料 |
|---|---|---|
tpe |
臺北市政府 | 臺北市政府行政機關辦公日曆表 |
nwt |
新北市政府 | 政府行政機關辦公日曆表 |
代碼採 ISO 3166-2:TW 地區碼:臺北市 TPE →
tpe、新北市 NWT →nwt。
兩來源原始 CSV 僅列「特殊日」(週末、放假日、補班日),平日不列。本專案會補齊全年每一天。
每年一檔,位於 data/YYYY.json:
{
"year": 2025,
"sources": ["tpe", "nwt"],
"summary": { "total": 365, "workdays": 247, "holidays": 118 },
"days": [
{
"date": "2025-01-01",
"weekday": 3,
"isWorkday": false,
"name": "中華民國開國紀念日",
"category": "放假之紀念日及節日",
"description": "全國各機關學校放假一日。"
}
]
}欄位說明:
year:西元年。sources:本年資料來源代碼。兩來源皆涵蓋並通過交叉驗證時為["tpe","nwt"];僅單一來源涵蓋時為["tpe"]或["nwt"]。summary:total全年天數、workdays上班日數、holidays放假日數。days[]:全年每一天,依日期排序。date:YYYY-MM-DD。weekday:ISO 星期(1=週一 … 7=週日)。isWorkday:一般機關學校當日是否上班(核心欄位)。name/category/description:若為來源特殊日則填入,否則為空字串。
JSON 以 UTF-8、不轉義中文、2 空白縮排輸出,且刻意不含產生時間戳,使資料無變更時不會產生雜訊 commit。
isWorkday 以「星期一~五上班、週六日放假」為基準,再依來源的 holidayCategory 覆蓋:
| 分類 | 對一般機關 | 對 isWorkday |
|---|---|---|
| 星期六、星期日 / 星期日 | 放假 | False |
| 放假之紀念日及節日 | 放假 | False |
| 補假 | 放假 | False |
| 調整放假日 | 放假 | False |
| 補行上班 / 補行上班日 | 補班(上班) | True(覆蓋週末) |
| 特定節日(如警察節、勞動節) | 一般機關照常 | 不覆蓋,依基準 |
| 紀念日及節日(如婦女節、教師節) | 一般機關照常 | 不覆蓋,依基準 |
「特定節日」與無「放假之」前綴的「紀念日及節日」是職業別或純紀念性質,一般行政機關照常上班,僅保留名稱供參考。若來源出現程式未定義的新分類,會自動開 issue 並中斷(見下)。
需要 uv。
# 預設只處理「來年」(例如 2026 年執行 → 產生 data/2027.json)
uv run twcal
# 指定年份(逗號分隔),不影響其他年份
uv run twcal --year 2025
uv run twcal --year 2025,2026
# 指定輸出目錄(預設 data)
uv run twcal --year 2025 --data-dir data
# 執行測試
uv run pytest預設只處理來年是為了避免既有的過去年份資料被異動;要補產特定年份再用 --year 指定。
data/viewer.html 是一支純前端、零依賴的檢視工具,把 data/YYYY.json 以官方「辦公日曆表」的版面呈現:每月一格、一列三格共十二格,上班日白底、放假日淡粉紅底,方便快速目視整年的上班/放假分布。
工具與 YYYY.json 同目錄,支援兩種開啟方式:
-
直接用瀏覽器開啟(免伺服器):雙擊
data/viewer.html即可(file://)。因瀏覽器禁止網頁用fetch()讀取本機檔案,工具會自動改為顯示「選擇檔案」介面,由你手動選取或拖放YYYY.json。 -
透過本機 web server(可用
?file=自動載入):cd data python3 -m http.server 8000 # 瀏覽器開啟 http://127.0.0.1:8000/viewer.html?file=2026.json
也可將 data/ 目錄部署到任何靜態主機(GitHub Pages、S3、Nginx 等)後以 ?file= 直接存取。放假/上班直接採用 JSON 的 isWorkday 欄位,補班、補假與 overrides.json 覆寫結果都會正確反映。
工具刻意零第三方套件(避免供應鏈攻擊),並對 file 參數做嚴格白名單驗證 ^[0-9]{4}\.json$、全程以 textContent 渲染(避免路徑穿越與 XSS)。詳細說明、資安設計與客製方式見 docs/viewer.md。
GitHub Actions(.github/workflows/update-calendar.yml)於每年 7–12 月的 1 日與 15 日自動執行,處理來年資料;data/ 有變更才會自動 commit。也可在 Actions 頁面手動觸發(workflow_dispatch),並可輸入指定年份。
若執行時來年資料尚未由來源公告,視為「尚未發布」,正常結束、不產檔、不開 issue。
維護者發版(打 tag、開 Release)的版本策略與步驟見
docs/release.md。
當發生下列情況時,程式會自動開 issue 並中斷(完全不寫檔),交由開發者判斷處理,而非寫出可疑資料:
- 兩來源不一致:同一日期推導後的「是否上班」結果不同(例如某年某來源尚未反映法規變更)。
- 欄位/格式變動:來源 CSV 欄位與預期不符(來源改版)。
- 未知分類:出現程式未定義的
holidayCategory,無法判斷是否上班。
issue 會依標題去重,避免每月重複開啟。單一來源下載失敗時不視為錯誤,會改用另一來源照常產出;兩來源皆失敗才會讓工作失敗(由 GitHub 原生通知)。
兩來源不一致時(例如某來源尚未反映法規變更),確認哪個來源正確後,於專案根目錄 overrides.json 新增該日期並指定信任來源,commit 後下次執行即自動套用、正常產出,不需修改程式碼:
{
"2026-05-01": {
"trust": "tpe",
"reason": "勞動節2026起升格全國國定假日,新北來源尚未更新,以臺北為準。"
}
}trust 為來源代碼(tpe 或 nwt)。被覆寫的日期會改採該來源的記錄與推導結果,其餘日期仍正常交叉驗證;對未覆寫的新歧異仍會開 issue 中斷。issue 內文會附上可直接套用的範例。
本專案已內建一筆
2026-05-01(勞動節)覆寫作為範例。
本專案程式碼(taiwan_work_calendar/、tests/ 等)採用 MIT License 釋出,可自由使用、修改與散布。
data/ 內產出的 JSON 係由臺北市政府、新北市政府開放資料平台之「辦公日曆表」轉換而來。原始資料著作權屬各來源機關及行政院人事行政總處所有,其再利用仍受各開放資料平台之授權條款(一般為《政府資料開放授權條款-第1版》)規範。本專案僅做格式轉換,未變更其事實內容。
- 本專案為非官方工具,與臺北市政府、新北市政府及行政院人事行政總處無任何隸屬關係。
- 一切以官方公告之辦公日曆表為準。本專案資料雖經兩來源交叉驗證,仍可能因來源更新延遲或轉換瑕疵而與官方不符。
- 資料依「現狀」(as-is)提供,作者不對其正確性、完整性或可用性負責;使用者應自行承擔使用風險。