Consolidate desktop controls with editable holidays and a running-window tray

This commit is contained in:
aria committed 2026-10-28 06:02:46 +09:00
1 parent 9908dde9f8
commit 326465952a
55 files changed
+4207 -450

No files matched your search

@@ -0,0 +1,82 @@
// 日本祝日计算函数。返回 YYYY-MM-DD → 节假日名称的映射。
// weekday(date) 的周日为 0;date(year, month, day) 与 add_days(date, n) 生成日期。
// 规则适用 1955–2099 年;未公布年份的春秋分日为近似计算。
fn monday(year, month, nth) {
let first = date(year, month, 1);
1 + (8 - weekday(first)) % 7 + 7 * (nth - 1)
}
fn japanese_holidays(year) {
let h = #{};
if year < 1955 || year > 2099 { return h; }
h[date(year, 1, 1)] = "元日";
h[date(year, 1, if year >= 2000 { monday(year, 1, 2) } else { 15 })] = "成人の日";
if year >= 1967 { h[date(year, 2, 11)] = "建国記念の日"; }
if year >= 2020 { h[date(year, 2, 23)] = "天皇誕生日"; }
if year >= 1989 && year <= 2018 { h[date(year, 12, 23)] = "天皇誕生日"; }
h[date(year, 4, 29)] = if year >= 2007 { "昭和の日" }
else if year >= 1989 { "みどりの日" } else { "天皇誕生日" };
// 春分・秋分近似式。官报公布前的将来日期仅为推算。
let spring_base = if year < 1980 { 20.8357 } else { 20.8431 };
let autumn_base = if year < 1980 { 23.2588 } else { 23.2488 };
let leap_base = if year < 1980 { 1983 } else { 1980 };
let shift = 0.242194 * (year - 1980) - (year - leap_base) / 4;
h[date(year, 3, floor(spring_base + shift))] = "春分の日";
h[date(year, 9, floor(autumn_base + shift))] = "秋分の日";
h[date(year, 5, 3)] = "憲法記念日";
if year >= 2007 { h[date(year, 5, 4)] = "みどりの日"; }
h[date(year, 5, 5)] = "こどもの日";
h[date(year, 11, 3)] = "文化の日";
h[date(year, 11, 23)] = "勤労感謝の日";
if year >= 1966 {
h[date(year, 9, if year >= 2003 { monday(year, 9, 3) } else { 15 })] = "敬老の日";
let sport = if year == 2020 { date(year, 7, 24) }
else if year == 2021 { date(year, 7, 23) }
else { date(year, 10, if year >= 2000 { monday(year, 10, 2) } else { 10 }) };
h[sport] = if year >= 2020 { "スポーツの日" }
else if year == 2019 { "体育の日(スポーツの日)" } else { "体育の日" };
}
if year >= 1996 {
let sea = if year == 2020 { date(year, 7, 23) }
else if year == 2021 { date(year, 7, 22) }
else { date(year, 7, if year >= 2003 { monday(year, 7, 3) } else { 20 }) };
h[sea] = "海の日";
}
if year >= 2016 {
h[date(year, 8, if year == 2020 { 10 } else if year == 2021 { 8 } else { 11 })] = "山の日";
}
// 即位・成婚等の特例。
if year == 1959 { h[date(year, 4, 10)] = "結婚の儀"; }
if year == 1989 { h[date(year, 2, 24)] = "大喪の礼"; }
if year == 1990 { h[date(year, 11, 12)] = "即位礼正殿の儀"; }
if year == 1993 { h[date(year, 6, 9)] = "結婚の儀"; }
if year == 2019 {
h[date(year, 5, 1)] = "休日(祝日扱い)";
h[date(year, 10, 22)] = "休日(祝日扱い)";
}
let national = h;
let first = date(year, 1, 1);
// 祝日に挟まれた日:1986 年から適用、日曜日は対象外。
if year >= 1986 {
for day in 0..days_in_year(year) {
let d = add_days(first, day);
if weekday(d) != 0 && !h.contains(d)
&& national.contains(add_days(d, -1)) && national.contains(add_days(d, 1)) {
h[d] = "休日";
}
}
}
// 振替休日:1973 年導入、2007 年以降は次の祝日でない日まで繰り越す。
for d in national.keys() {
if d >= "1973-04-12" && weekday(d) == 0 {
let substitute = add_days(d, 1);
if year >= 2007 {
while h.contains(substitute) { substitute = add_days(substitute, 1); }
}
if !h.contains(substitute) { h[substitute] = "休日"; }
}
}
h
}