UWSCで祝日を算出する

UWSCの公式掲示板で祝日絡みの質問があった。
stuncloudさんが回答していたので、ま、質問自体は放置ですが、オフラインで算出する方法を考えてみた。

追記 2021/10/12
2020/2021年東京オリンピック周りの変更等を反映
追記 2018/6/25
2020年東京オリンピック周りの変更等を反映
追記 2014/05/27
「山の日」追加
追記 2013/07/25
2006年以前が気になる場合も考えてみた。
UWSCで1949年以降の祝日を算出する - じゅんじゅんのきまぐれ
2007年以降は、シンプルなのでこの記事のがお勧め。

スクリプト

stuncloudさんの回答にあわせた関数にしてみました。

FUNCTION GetHolidayList(y=EMPTY)
	// 注意! 現在の仕様のため、2006年以前と変更されたら修正が必要です
	IFB y = EMPTY THEN
		GETTIME()
		y = G_TIME_YY
	ENDIF

	HASHTBL tbl = HASH_SORT

	// 固定組
	IFB y >= 1989 AND y < 2019 THEN
		tbl[y+"-12-23"] = "天皇誕生日"		// 平成より前は未対応
	ELSEIF y > 2019 THEN
		tbl[y+"-02-23"] = "天皇誕生日"		// 本来はyによる判定が必要
	ENDIF
	tbl[y+"-01-01"] = "元日"
	tbl[y+"-02-11"] = "建国記念の日"	// 紀元節。建国記念の日としては1967年から
	tbl[y+"-04-29"] = "昭和の日"		// 2007年から。昭和天皇誕生日→みどりの日(1989-)
	tbl[y+"-05-03"] = "憲法記念日"		// 1948年から
	tbl[y+"-05-04"] = "みどりの日"		// 2007年に4/29から移動
	tbl[y+"-05-05"] = "こどもの日"
	tbl[y+"-11-03"] = "文化の日"		// 明治節
	tbl[y+"-11-23"] = "勤労感謝の日"	// 新嘗祭。1873年からか?
	IFB y = 2019 THEN
		tbl[y+"-05-01"] = "休日"	// 令和天皇の即位
		tbl[y+"-10-22"] = "休日"	// 令和天皇の即位礼正殿の儀
	ENDIF

	// 第n月曜組(ハッピーマンデー)+山の日
	tbl[GetNthDay(2, 1, y+"-01-15")] = "成人の日"	// 2000年に移動。1949年から
	tbl[GetNthDay(3, 1, y+"-09-15")] = "敬老の日"	// 2003年に移動。1966年から
	IFB y = 2020 THEN
		tbl[y+"-07-23"] = "海の日"					// 2020年東京オリンピック開会式にあわせて
		tbl[y+"-07-24"] = "スポーツの日"			// 2020年東京オリンピック開会式にあわせて
		tbl[y+"-08-10"] = "山の日"					// 2020年東京オリンピック閉会式にあわせて
	ELSEIF y = 2021 THEN
		tbl[y+"-07-22"] = "海の日"					// 2020年東京オリンピック開会式にあわせて
		tbl[y+"-07-23"] = "スポーツの日"			// 2020年東京オリンピック開会式にあわせて
		tbl[y+"-08-08"] = "山の日"					// 2020年東京オリンピック閉会式にあわせて
	ELSE
		IF y > 2015 THEN tbl[y+"-08-11"] = "山の日"	// 2016年から
		tbl[GetNthDay(3, 1, y+"-07-20")] = "海の日"	// 2003年に移動。1996年から
		tbl[GetNthDay(2, 1, y+"-10-10")] = "スポーツの日"	// 2000年に移動。1966年から。2020年から「体育の日」から名称変更
	ENDIF

	// 春分の日・秋分の日(1980-2100用)
	DIM b = y - 1980, i = 0
	tbl[y+"-03-"+(INT(20.8431+0.242194*b)-INT(b/4))] = "春分の日"
	tbl[y+"-09-"+(INT(23.2488+0.242194*b)-INT(b/4))] = "秋分の日"

	// 振替休日 1973年から
	WHILE i < LENGTH(tbl)
		GETTIME(1, tbl[i, HASH_KEY])
		b = G_TIME_YY4 + "-" + G_TIME_MM2 + "-" + G_TIME_DD2
		IFB G_TIME_WW = 1 THEN
			WHILE tbl[b, HASH_EXISTS]
				GETTIME(1, b)
				b = G_TIME_YY4 + "-" + G_TIME_MM2 + "-" + G_TIME_DD2
				i = i + 1
			WEND
			tbl[b] = "振替休日"
			i = i + 1
		ENDIF
		i = i + 1
	WEND

	// 国民の休日 1988年から
	i = 1
	WHILE i < LENGTH(tbl)
		IFB GETTIME(1, tbl[i-1, HASH_KEY]) = GETTIME(-1, tbl[i, HASH_KEY]) THEN
			tbl[G_TIME_YY4+"-"+G_TIME_MM2+"-"+G_TIME_DD2] = "国民の休日"
			i = i + 1
		ENDIF
		i = i + 1
	WEND

	// 結果格納
	RESULT = SAFEARRAY(0, LENGTH(tbl) - 1)
	FOR i = 0 TO LENGTH(tbl) - 1
		RESULT[i] = tbl[i, HASH_KEY]
	NEXT
FEND
FUNCTION GetNthDay(n, w, b=EMPTY)
	IF b <> EMPTY THEN GETTIME(0, b)
	DIM d = 1 - G_TIME_DD
	GETTIME(d, b)	// 月初日の曜日取得
	w = w - G_TIME_WW
	d = d + w + ((w < 0) + n - 1) * 7	// 第n分ずらす
	GETTIME(d, b)
	RESULT = G_TIME_YY4 + "-" + G_TIME_MM2 + "-" + G_TIME_DD2
FEND

コメントでいろいろ有効になった時期とか書いてます。
戦前になくなったものは、未考慮です。
1948年以降であれば、判定を適宜入れれば使えるかと。

ちなみに

stuncloudさんの回答は
No.4923への回答 | たっぷす庵
なんだけど、いくつか。

  • start-maxは、翌年1月1日が良いです。
    • 12/31が祝日だと、取れません(たしか)
  • 今回は関係ないですが、カレンダーは登録順?なので、ソートするのがお勧め
  • あのカレンダーは誰のだろう?
    • Google公式もありますが精度がよくないです
    • mozila.orgの「outid3el0qkcrsuf89fltf7a4qbacgt9@import.calendar.google.com」もおすすめ