Files
feresaria/crates/ferese-config/data/japanese-holidays.rhai

83 lines
3.8 KiB
Plaintext
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// 日本祝日计算函数。返回 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
}