getNthWeekdayゲットエヌスウィークデイ

指定年月のn回目のw曜日(第nW曜日)の日付を返します。年・月どちらかでも省略されたら当月として計算。

構文
getNthWeekday( n, w, year, month )
引数
n 必須
月何週目かを数値で指定。マイナス値で後ろから。
w 必須
0:日曜~6:土曜で数値を指定
year 省略可
month 省略可
戻り値
指定年月の第n週w曜日の日付を返します。

プログラム

UWSC
//////////////////////////////////////////////////
// 【引数】
//   n : 月何週目かを数値で指定。マイナス値で後ろから。 
//   w : 0:日曜~6:土曜で数値を指定 
//   year : 年 
//   month : 月 
// 【戻り値】
//   指定年月の第n週w曜日の日付を返します。 
//////////////////////////////////////////////////
FUNCTION getNthWeekday(n, w, year = EMPTY, month = EMPTY)
	IFB year = EMPTY OR month = EMPTY THEN
		date = EMPTY
	ELSE
		date = year + "/" + IIF(LENGTH(month) = 1, "0", "") + month + "/01"
	ENDIF
	GETTIME(0, date)
	DIM yyyy = G_TIME_YY
	DIM mm = G_TIME_MM
	IFB w < 0 OR w > 7 THEN
		RESULT = ERR_VALUE
		EXIT
	ENDIF
	IFB n > 0 THEN
		GETTIME(0, date)
		d = 1 - G_TIME_DD
		GETTIME(d, date)
		w = w - G_TIME_WW
		d = d + w + ((w < 0) + n - 1) * 7
		GETTIME(d, date)
	ELSEIF n < 0 THEN
		date = getEndOfMonth(date)
		DIM serial = uwscToSerial(GETTIME(0, date))
		serial = INT((serial + (6 - w)) / 7) * 7 - (6 - w) - 7 * (n + 1)
		DIM uwscTime = serialToUwsc(serial)
		GETTIME(uwscTime / 86400, "20000101000000")
	ENDIF
	RESULT = G_TIME_YY4 + "/" + G_TIME_MM2 + "/" + G_TIME_DD2
FEND

//////////////////////////////////////////////////
// 【引数】
//   interval : 加算する時間間隔を表す文字列式(yyyy:年、m:月、d:日、ww:週、h:時、n:分、s:秒) 
//   num : dateに加算する値。未来は正、過去は負で指定 
//   date : 時間間隔を加算する日付 
// 【戻り値】
//   日時(date)に、指定した単位(interval)の時間(num)を加算して返します 
//////////////////////////////////////////////////
FUNCTION dateAdd(interval, num, date)
	DIM year, month, day, d
	GETTIME(0, date)
	DIM time = G_TIME_HH2 + ":" + G_TIME_NN2 + ":" + G_TIME_SS2
	SELECT interval
		CASE "yyyy"
			d = (G_TIME_YY + num) + "/" + G_TIME_MM2 + "/" + G_TIME_DD2
			IF time <> "00:00:00" THEN d = d + " " + time
		CASE "m"
			IFB num > 0 THEN
				year = G_TIME_YY + INT((G_TIME_MM + num) / 12)
				month = REPLACE(FORMAT(((G_TIME_MM + num) MOD 12), 2), " ", "0")
			ELSE
				year = G_TIME_YY + CEIL((G_TIME_MM + num) / 12 - 1)
				month = REPLACE(FORMAT(G_TIME_MM - (ABS(num) MOD 12), 2), " ", "0")
			ENDIF
			IF month = "00" THEN month = 12
			day = G_TIME_DD2
			d = "" + year + month + day
			IFB !isDate(d) THEN
				d = year + "/" + month + "/" + "01"
				d = getEndOfMonth(d)
			ELSE
				d = year + "/" + month + "/" + day
			ENDIF
			IF time <> "00:00:00" THEN d = d + " " + time
		CASE "d"
			t = GETTIME(num, date)
			d = G_TIME_YY4 + "/" + G_TIME_MM2 + "/" + G_TIME_DD2 + IIF(t MOD 86400, " " + G_TIME_HH2 + ":" + G_TIME_NN2 + ":" + G_TIME_SS2, "")
		CASE "ww"
			t = GETTIME(num * 7, date)
			d = G_TIME_YY4 + "/" + G_TIME_MM2 + "/" + G_TIME_DD2 + IIF(t MOD 86400, " " + G_TIME_HH2 + ":" + G_TIME_NN2 + ":" + G_TIME_SS2, "")
		CASE "h"
			t = GETTIME(num / 24, date)
			d = G_TIME_YY4 + "/" + G_TIME_MM2 + "/" + G_TIME_DD2 + IIF(t MOD 86400, " " + G_TIME_HH2 + ":" + G_TIME_NN2 + ":" + G_TIME_SS2, "")
		CASE "n"
			t = GETTIME(num / 1440, date)
			d = G_TIME_YY4 + "/" + G_TIME_MM2 + "/" + G_TIME_DD2 + IIF(t MOD 86400, " " + G_TIME_HH2 + ":" + G_TIME_NN2 + ":" + G_TIME_SS2, "")
		CASE "s"
			t = GETTIME(num / 86400, date)
			d = G_TIME_YY4 + "/" + G_TIME_MM2 + "/" + G_TIME_DD2 + IIF(t MOD 86400, " " + G_TIME_HH2 + ":" + G_TIME_NN2 + ":" + G_TIME_SS2, "")
	SELEND
	RESULT = d
FEND

//////////////////////////////////////////////////
// 【引数】
//   date : 日付(”YYYYMMDD” or “YYYY/MM/DD” or “YYYY-MM-DD” or “YYYYMMDDHHNNSS” or “YYYY/MM/DD HH:NN:SS”) 
//   m : 第一引数の指定日からプラスマイナスm月とする 
// 【戻り値】
//   dateからm月後の月末の日付 
//////////////////////////////////////////////////
FUNCTION getEndOfMonth(date, m = 0)
	date = dateAdd("m", m + 1, date)
	GETTIME(0, date)
	GETTIME(-G_TIME_DD, date)
	RESULT = G_TIME_YY4 + "/" + G_TIME_MM2 + "/" + G_TIME_DD2
FEND

//////////////////////////////////////////////////
// 【引数】
//   expr : 評価する式 
//   truepart : 評価した式がTrueのときに返す値 
//   falsepart : 評価した式がFalseのときに返す値 
// 【戻り値】
//   truepart : 評価した式がTrueのとき、falsepart : 評価した式がFalseのとき 
//////////////////////////////////////////////////
FUNCTION IIF(expr, truepart, falsepart)
	IFB EVAL(expr) THEN
		RESULT = truepart
	ELSE
		RESULT = falsepart
	ENDIF
FEND

//////////////////////////////////////////////////
// 【引数】
//   date : 存在するかを調べる日付文字列。YYYYMMDD or YYYY/MM/DD or YYYY-MM-DDのいずれかの形式。 
// 【戻り値】
//   TRUE : 日付として認識できる、FALSE : 日付として認識できない 
//////////////////////////////////////////////////
FUNCTION isDate(date)
	TRY
		GETTIME(0, date)
		RESULT = TRUE
	EXCEPT
		RESULT = FALSE
	ENDTRY
FEND

//////////////////////////////////////////////////
// 【引数】
//   serialTime : シリアル値 
// 【戻り値】
//   UWSC時間 
//////////////////////////////////////////////////
FUNCTION serialToUwsc(serialDate)
	RESULT = GETTIME(serialDate, "18991230000000")
FEND

//////////////////////////////////////////////////
// 【引数】
//   uwscTime : UWSC時間 
// 【戻り値】
//   シリアル値 
//////////////////////////////////////////////////
FUNCTION uwscToSerial(uwscTime)
	uwscDate = uwscTime / 86400
	RESULT = 36526 + uwscDate
FEND

使い方

第1月曜日(w=1)

UWSC
PRINT getNthWeekday(1, 1)

第3金曜日(w=5)

UWSC
PRINT getNthWeekday(3, 5)

成人の日(1月の第2月曜日)

UWSC
PRINT getNthWeekday(2, 1, getYear(today()), 1)

海の日(7月の第3月曜日)

UWSC
PRINT getNthWeekday(3, 1, getYear(today()), 7)

敬老の日(9月の第3月曜日)

UWSC
PRINT getNthWeekday(3, 1, getYear(today()), 9)

スポーツの日(10月の第2月曜日)

UWSC
PRINT getNthWeekday(2, 1, getYear(today()), 10)

プレミアムフライデー(毎月最終金曜日)

UWSC
PRINT getNthWeekday(-1, 5)

ブラックフライデー(11月の第4木曜日の翌日)

UWSC
PRINT dateAdd("d", 1, getNthWeekday(4, 4, getYear(today()), 11))

この記事は役に立ちましたか?

はい
いいえ
ご協力ありがとうございます。

関連記事

getWeekdayName (自作関数)
GETTIMEで取得した曜日の番号を指定したフォーマットで返します。
getWeekday (自作関数)
引数に指定された日付の曜日番号(0:日曜〜6:土曜)を返します。
GETTIME関数 (スクリプト関数)
日付、時間を取得します。
getYear (自作関数)
指定された日付のを返します。
getMonth (自作関数)
指定された日付のを返します。
getDay (自作関数)
指定された日付のを返します。
isDate (自作関数)
引数に指定した値が日付として認識できる場合はTrueを返します。認識できない場合はFalseを返します。
getEndOfMonth (自作関数)
dateで指定された月の月末日を取得します。
today (自作関数)
今日の日付を返します。
dateString (自作関数)
指定された日付を西暦から 和暦 に変換します。