本ページには広告が含まれています。
指定した ユリウス日 の直前の 朔 を求めます。 グレゴリオ暦 をユリウス日に変換するには、YMDToJD関数 (自作関数)を使います。
- 構文
- saku( JD )
- 引数
- JD 必須
- ユリウス日
- 戻り値
- 朔の日時
プログラム
////////////////////////////////////////////////// // 【引数】 // JD : ユリウス日 // 【戻り値】 // 朔の日時 ////////////////////////////////////////////////// FUNCTION saku(JD) DIM lc = 1 // loop counter DIM JD1 = INT(JD) DIM JD2 = JD - JD1 JD2 = JD2 - 9/24 DIM Δt1 = 0 DIM Δt2 = 1 WHILE ABS(Δt1+Δt2) > 1/86400 DIM JC = (JD2 + 0.5) / 36525 JC = JC + (JD1 - 2451545) / 36525 DIM λsun = longitudeSun(JC) DIM λmoon = longitudeMoon(JC) DIM Δλ = λmoon - λsun SELECT TRUE CASE lc = 1 AND Δλ < 0 Δλ = normalizeAngle(Δλ) CASE λsun >= 0 AND λsun <= 20 AND λmoon >= 300 Δλ = normalizeAngle(Δλ) Δλ = 360 - Δλ CASE ABS(Δλ) > 40 Δλ = normalizeAngle(Δλ) SELEND Δt1 = INT(Δλ * 29.530589 / 360) Δt2 = Δλ * 29.530589 / 360 Δt2 = Δt2 - Δt1 JD1 = JD1 - Δt1 JD2 = JD2 - Δt2 IFB JD2 < 0 THEN JD2 = JD2 + 1 JD1 = JD1 - 1 ENDIF IFB lc = 15 AND ABS(Δt1+Δt2) > 1/86400 THEN JD1 = INT(JD - 26) JD2 = 0 ELSEIF lc > 30 AND ABS(Δt1+Δt2) > 1/86400 JD1 = JD JD2 = 0 ENDIF lc = lc + 1 WEND RESULT = JD1 + JD2 + 9/24 FEND ////////////////////////////////////////////////// // 【引数】 // deg : 角度(度数法) // 【戻り値】 // 度数法から弧度法に変換した値 ////////////////////////////////////////////////// FUNCTION degToRad(deg) RESULT = deg * (3.14159265358979 / 180) FEND ////////////////////////////////////////////////// // 【引数】 // JC : ユリウス世紀 // 【戻り値】 // 月黄経(λmoon) ////////////////////////////////////////////////// FUNCTION longitudeMoon(JC) DIM A[63] = 0.0003, 0.0003, 0.0003, 0.0003, 0.0003, 0.0003, 0.0003, 0.0004, 0.0004, 0.0005, 0.0005, 0.0005, 0.0006, 0.0006, 0.0007, 0.0007, 0.0007, 0.0007, 0.0008, 0.0009, 0.0011, 0.0012, 0.0016, 0.0018, 0.0021, 0.0021, 0.0021, 0.0022, 0.0023, 0.0024, 0.0026, 0.0027, 0.0028, 0.0037, 0.0038, 0.004, 0.004, 0.004, 0.005, 0.0052, 0.0068, 0.0079, 0.0085, 0.01, 0.0107, 0.011, 0.0125, 0.0154, 0.0304, 0.0347, 0.0409, 0.0458, 0.0533, 0.0571, 0.0588, 0.1144, 0.1851, 0.2136, 0.6583, 1.274, 6.2888, 481267.8809 * JC, 218.3162 DIM k[63] = 2322131, 4067, 549197, 1808933, 349472, 381404, 958465, 12006, 39871, 509131, 1745069, 1908795, 2258267, 111869, 27864, 485333, 405201, 790672, 1403732, 858602, 1920802, 1267871, 1856938, 401329, 341337, 71998, 990397, 818536, 922466, 99863, 1379739, 918399, 1934, 541062, 1781068, 133, 1844932, 1331734, 481266, 31932, 926533, 449334, 826671, 1431597, 1303870, 489205, 1443603, 75870, 513197.9, 445267.1, 441199.8, 854535.2, 1367733.1, 377336.3, 63863.5, 966404, 35999, 954397.7, 890534.2, 413335.3, 477198.9, 0, 0 DIM θ0[63] = 191, 70, 220, 58, 337, 354, 340, 187, 223, 242, 24, 90, 156, 38, 127, 186, 50, 114, 98, 129, 186, 249, 152, 274, 16, 85, 357, 151, 163, 122, 17, 182, 145, 259, 21, 29, 56, 283, 205, 107, 323, 188, 111, 315, 246, 142, 52, 41, 222.5, 27.9, 47.4, 148.2, 280.7, 13.2, 124.2, 276.5, 87.53, 179.93, 145.7, 10.74, 44.963, 0, 0 DIM λmoon[63] FOR n = 0 TO 60 DIM ang = normalizeAngle(k[n] * JC + θ0[n]) λmoon[n] = A[n] * COS(degToRad(ang)) NEXT λmoon[61] = normalizeAngle(A[61]) λmoon[62] = normalizeAngle(A[62]) RESULT = normalizeAngle(CALCARRAY(λmoon, CALC_ADD)) FEND ////////////////////////////////////////////////// // 【引数】 // JC : ユリウス世紀 // 【戻り値】 // 太陽黄経(λsun) ////////////////////////////////////////////////// FUNCTION longitudeSun(JC) DIM A[18] = 0.0004, 0.0004, 0.0005, 0.0005, 0.0006, 0.0007, 0.0007, 0.0007, 0.0013, 0.0015, 0.0018, 0.0018, 0.0020, 0.0200, -0.0048*JC, 1.9147, 36000.7695*JC, 280.4659 DIM k[18] = 31557.0, 29930.0, 2281.0, 155.0, 33718.0, 9038.0, 3035.0, 65929.0, 22519.0, 45038.0, 445267.0, 19.0, 32964.0, 71998.1, 35999.05, 35999.05, 0, 0 DIM θ0[18] = 161.0, 48.0, 221.0, 118.0, 316.0, 64.0, 110.0, 45.0, 352.0, 254.0, 208.0, 159.0, 158.0, 265.1, 267.52, 267.52, 0, 0 DIM λsun[18] FOR n = 0 TO 15 DIM ang = normalizeAngle(k[n] * JC + θ0[n]) λsun[n] = A[n] * COS(degToRad(ang)) NEXT λsun[16] = normalizeAngle(A[16]) λsun[17] = normalizeAngle(A[17]) RESULT = normalizeAngle(CALCARRAY(λsun, CALC_ADD)) FEND ////////////////////////////////////////////////// // 【引数】 // deg : 度数法 // 【戻り値】 // 度単位の角度を0~360度に正規化 ////////////////////////////////////////////////// FUNCTION normalizeAngle(deg) SELECT TRUE CASE deg >= 360 deg = deg - INT(deg / 360) * 360 CASE deg < 0 deg = deg + INT(ABS(deg / 360) + 1) * 360 SELEND RESULT = deg FEND
プログラム実行例
月齢計算
DIM today = today() DIM year = getYear(today()) DIM month = getMonth(today()) DIM lastDay = getDay(getEndOfMonth(today())) FOR day = 1 TO lastDay DIM JD = saku(YMDToJD(year, month, day, 12, 0, 0)) DIM d = JDToYMD(JD) DIM date1 = d[0] + "/" + text(d[1], "00") + "/" + text(d[2], "00") + " " + text(d[3], "00") + ":" + d[4] + ":" + d[5] DIM date2 = year + "/" + text(month, "00") + "/" + text(day, "00") + " 12:00:00" PRINT year + "/" + month + "/" + day + "<#TAB>" + ROUND(dateDiff("d", date1, date2), -1) NEXT ////////////////////////////////////////////////// // 【引数】 // 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 ////////////////////////////////////////////////// // 【引数】 // interval : 時間単位(yyyy︰年、q:四半期、m︰月、d︰日、w:週日、ww:週、h:時、n:分、s:秒) // date1 : 日時1 // date2 : 日時2 // 【戻り値】 // date2からdate1を引いた時間間隔を求めます。 ////////////////////////////////////////////////// FUNCTION dateDiff(interval, date1, date2) DIM y1, y2, m1, m2, d1, d2, d SELECT interval CASE "yyyy" GETTIME(0, date1) y1 = G_TIME_YY GETTIME(0, date2) y2 = G_TIME_YY d = y2 - y1 CASE "q" GETTIME(0, date1) y1 = G_TIME_YY m1 = G_TIME_MM GETTIME(0, date2) y2 = G_TIME_YY m2 = G_TIME_MM d = y2 * 4 + CEIL(m2/3) - (y1 * 4 + CEIL(m1/3)) CASE "m" GETTIME(0, date1) y1 = G_TIME_YY m1 = G_TIME_MM GETTIME(0, date2) y2 = G_TIME_YY m2 = G_TIME_MM d = (y2 - y1) * 12 + m2 - m1 CASE "d" d1 = GETTIME(0, date1) d2 = GETTIME(0, date2) d = (d2 - d1) / 86400 CASE "w" d = INT(dateDiff("d", date1, date2) / 7) CASE "ww" date1 = dateAdd("d", -1 * getWeekday(date1), date1) d = INT(dateDiff("d", date1, date2) / 7) CASE "h" d = dateDiff("d", date1, date2) * 24 CASE "n" d = dateDiff("d", date1, date2) * 1440 CASE "s" d = dateDiff("d", date1, date2) * 86400 SELEND RESULT = d FEND ////////////////////////////////////////////////// // 【引数】 // deg : 角度(度数法) // 【戻り値】 // 度数法から弧度法に変換した値 ////////////////////////////////////////////////// FUNCTION degToRad(deg) RESULT = deg * (3.14159265358979 / 180) FEND ////////////////////////////////////////////////// // 【引数】 // array : 最大公約数を求める数値を格納した配列 // 【戻り値】 // 最大公約数 ////////////////////////////////////////////////// FUNCTION GCD(array[]) DIM c = LENGTH(array) DIM rem = array[c-1] MOD array[c-2] IFB rem = 0 THEN IFB LENGTH(array) = 2 THEN RESULT = array[c-2] EXIT ENDIF RESIZE(array, c-2) RESULT = GCD(array) EXIT ENDIF array[c-1] = array[c-2] array[c-2] = rem RESULT = GCD(array) FEND ////////////////////////////////////////////////// // 【引数】 // date : 日付(”YYYYMMDD” or “YYYY/MM/DD” or “YYYY-MM-DD” or “YYYYMMDDHHNNSS” or “YYYY/MM/DD HH:NN:SS”) // 【戻り値】 // 指定した日付の「日」 ////////////////////////////////////////////////// FUNCTION getDay(date) GETTIME(0, date) RESULT = G_TIME_DD2 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 ////////////////////////////////////////////////// // 【引数】 // date : 日付(”YYYYMMDD” or “YYYY/MM/DD” or “YYYY-MM-DD” or “YYYYMMDDHHNNSS” or “YYYY/MM/DD HH:NN:SS”) // 【戻り値】 // 指定した日付の「月」 ////////////////////////////////////////////////// FUNCTION getMonth(date) GETTIME(0, date) RESULT = G_TIME_MM2 FEND ////////////////////////////////////////////////// // 【引数】 // date : 日付文字列(”YYYYMMDD” or “YYYY/MM/DD” or “YYYY-MM-DD” or “YYYYMMDDHHNNSS” or “YYYY/MM/DD HH:NN:SS”)もしくはシリアル値 // type : 取得する曜日番号の種類を示す0〜3または11〜17の値。1と17は日曜日を1、2と11は月曜日を1とカウントします。11以降はExcel2010で追加された値で、互換性を保つために重複した値があります。 // 【戻り値】 // typeで指定した種類によって以下の値を返します。 : (0 : 0(日曜)〜6(土曜)、1 : 1(日曜)~7(土曜)、2 : 1(月曜)~7(日曜)、3 : 0(月曜)〜6(日曜)、11 : 1(月曜)~7(日曜)、12 : 1(火曜)~7(月曜)、13 : 1(水曜)~7(火曜)、14 : 1(木曜)~7(水曜)、15 : 1(金曜)~7(木曜)、16 : 1(土曜)~7(金曜)、17 : 1(日曜)~7(土曜)) ////////////////////////////////////////////////// FUNCTION getWeekday(date, type = 1) IF VARTYPE(date) <> 258 THEN date = text(date, "yyyy/mm/dd") GETTIME(0, date) DIM w = G_TIME_WW SELECT TRUE CASE type = 0 RESULT = w CASE type = 1 RESULT = w + 1 CASE type = 2 RESULT = IIF(w=0, 7, w) CASE type = 3 RESULT = (w+6) MOD 7 CASE type >= 11 RESULT = ((getWeekday(date, 2) + 17 - type) MOD 7) + 1 SELEND FEND ////////////////////////////////////////////////// // 【引数】 // date : 日付(”YYYYMMDD” or “YYYY/MM/DD” or “YYYY-MM-DD” or “YYYYMMDDHHNNSS” or “YYYY/MM/DD HH:NN:SS”) // 【戻り値】 // 指定した日付の「年」 ////////////////////////////////////////////////// FUNCTION getYear(date) GETTIME(0, date) RESULT = G_TIME_YY4 FEND ////////////////////////////////////////////////// // 【引数】 // serial : シリアル値もしくは時刻文字列 // 【戻り値】 // 時刻から時間を表す0〜23の範囲の値 ////////////////////////////////////////////////// FUNCTION Hour(serial) IF VARTYPE(serial) = 258 THEN serial = timeValue(serial) RESULT = INT(serial * 24) MOD 24 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 ////////////////////////////////////////////////// // 【引数】 // JD : ユリウス日 // 【戻り値】 // グレゴリオ暦を格納した配列(0 : 年, 1 : 月, 2 : 日, 3 : 時, 4 : 分, 5 : 秒) ////////////////////////////////////////////////// FUNCTION JDToYMD(JD) DIM x0 = INT(JD + 68570) DIM x1 = INT(x0 / 36524.25) DIM x2 = x0 - INT(36524.25 * x1 + 0.75) DIM x3 = INT((x2 + 1) / 365.2425) DIM x4 = x2 - INT(365.25 * x3) + 31 DIM x5 = INT(INT(x4) / 30.59) DIM x6 = INT(INT(x5) / 11) DIM t2 = x4 - INT(30.59 * x5) DIM t1 = x5 - 12 * x6 + 2 DIM t0 = 100 * (x1 - 49) + x3 + x6 IFB t1 = 2 AND t2 > 28 THEN SELECT TRUE CASE t0 MOD 100 = 0 AND t0 MOD 400 = 0 t2 = 29 CASE t0 MOD 4 = 0 t2 = 29 DEFAULT t2 = 28 SELEND ENDIF DIM tm = 86400 * (JD - INT(JD)) DIM t3 = INT(tm / 3600) DIM t4 = INT((tm - 3600 * t3) / 60) DIM t5 = INT(tm - 3600 * t3 - 60 * t4) DIM t[] = t0, t1, t2, t3, t4, t5 RESULT = SLICE(t) FEND ////////////////////////////////////////////////// // 【引数】 // JC : ユリウス世紀 // 【戻り値】 // 月黄経(λmoon) ////////////////////////////////////////////////// FUNCTION longitudeMoon(JC) DIM A[63] = 0.0003, 0.0003, 0.0003, 0.0003, 0.0003, 0.0003, 0.0003, 0.0004, 0.0004, 0.0005, 0.0005, 0.0005, 0.0006, 0.0006, 0.0007, 0.0007, 0.0007, 0.0007, 0.0008, 0.0009, 0.0011, 0.0012, 0.0016, 0.0018, 0.0021, 0.0021, 0.0021, 0.0022, 0.0023, 0.0024, 0.0026, 0.0027, 0.0028, 0.0037, 0.0038, 0.004, 0.004, 0.004, 0.005, 0.0052, 0.0068, 0.0079, 0.0085, 0.01, 0.0107, 0.011, 0.0125, 0.0154, 0.0304, 0.0347, 0.0409, 0.0458, 0.0533, 0.0571, 0.0588, 0.1144, 0.1851, 0.2136, 0.6583, 1.274, 6.2888, 481267.8809 * JC, 218.3162 DIM k[63] = 2322131, 4067, 549197, 1808933, 349472, 381404, 958465, 12006, 39871, 509131, 1745069, 1908795, 2258267, 111869, 27864, 485333, 405201, 790672, 1403732, 858602, 1920802, 1267871, 1856938, 401329, 341337, 71998, 990397, 818536, 922466, 99863, 1379739, 918399, 1934, 541062, 1781068, 133, 1844932, 1331734, 481266, 31932, 926533, 449334, 826671, 1431597, 1303870, 489205, 1443603, 75870, 513197.9, 445267.1, 441199.8, 854535.2, 1367733.1, 377336.3, 63863.5, 966404, 35999, 954397.7, 890534.2, 413335.3, 477198.9, 0, 0 DIM θ0[63] = 191, 70, 220, 58, 337, 354, 340, 187, 223, 242, 24, 90, 156, 38, 127, 186, 50, 114, 98, 129, 186, 249, 152, 274, 16, 85, 357, 151, 163, 122, 17, 182, 145, 259, 21, 29, 56, 283, 205, 107, 323, 188, 111, 315, 246, 142, 52, 41, 222.5, 27.9, 47.4, 148.2, 280.7, 13.2, 124.2, 276.5, 87.53, 179.93, 145.7, 10.74, 44.963, 0, 0 DIM λmoon[63] FOR n = 0 TO 60 DIM ang = normalizeAngle(k[n] * JC + θ0[n]) λmoon[n] = A[n] * COS(degToRad(ang)) NEXT λmoon[61] = normalizeAngle(A[61]) λmoon[62] = normalizeAngle(A[62]) RESULT = normalizeAngle(CALCARRAY(λmoon, CALC_ADD)) FEND ////////////////////////////////////////////////// // 【引数】 // JC : ユリウス世紀 // 【戻り値】 // 太陽黄経(λsun) ////////////////////////////////////////////////// FUNCTION longitudeSun(JC) DIM A[18] = 0.0004, 0.0004, 0.0005, 0.0005, 0.0006, 0.0007, 0.0007, 0.0007, 0.0013, 0.0015, 0.0018, 0.0018, 0.0020, 0.0200, -0.0048*JC, 1.9147, 36000.7695*JC, 280.4659 DIM k[18] = 31557.0, 29930.0, 2281.0, 155.0, 33718.0, 9038.0, 3035.0, 65929.0, 22519.0, 45038.0, 445267.0, 19.0, 32964.0, 71998.1, 35999.05, 35999.05, 0, 0 DIM θ0[18] = 161.0, 48.0, 221.0, 118.0, 316.0, 64.0, 110.0, 45.0, 352.0, 254.0, 208.0, 159.0, 158.0, 265.1, 267.52, 267.52, 0, 0 DIM λsun[18] FOR n = 0 TO 15 DIM ang = normalizeAngle(k[n] * JC + θ0[n]) λsun[n] = A[n] * COS(degToRad(ang)) NEXT λsun[16] = normalizeAngle(A[16]) λsun[17] = normalizeAngle(A[17]) RESULT = normalizeAngle(CALCARRAY(λsun, CALC_ADD)) FEND ////////////////////////////////////////////////// // 【引数】 // deg : 度数法 // 【戻り値】 // 度単位の角度を0~360度に正規化 ////////////////////////////////////////////////// FUNCTION normalizeAngle(deg) SELECT TRUE CASE deg >= 360 deg = deg - INT(deg / 360) * 360 CASE deg < 0 deg = deg + INT(ABS(deg / 360) + 1) * 360 SELEND RESULT = deg FEND ////////////////////////////////////////////////// // 【引数】 // str : 正規表現による検索の対象となる文字列 // Pattern : 正規表現で使用するパターンを設定 // IgnoreCase : 大文字・小文字を区別しない場合はTrue、区別する場合はFalse // Global : 文字列全体を検索する場合はTrue、しない場合はFalse // 【戻り値】 // 正規表現で検索した結果をMatchesコレクションとして返します。 ////////////////////////////////////////////////// FUNCTION reExecute(str, Pattern, IgnoreCase = TRUE, Global = TRUE) DIM re = CREATEOLEOBJ("VBScript.RegExp") re.Pattern = Pattern re.IgnoreCase = IgnoreCase re.Global = Global RESULT = re.Execute(str) FEND ////////////////////////////////////////////////// // 【引数】 // str : 正規表現による検索の対象となる文字列 // Pattern : 正規表現で使用するパターンを設定 // IgnoreCase : 大文字・小文字を区別しない場合はTrue、区別する場合はFalse // Global : 文字列全体を検索する場合はTrue、しない場合はFalse // 【戻り値】 // 正規表現にマッチするかどうかを示すブール値 ////////////////////////////////////////////////// FUNCTION reTest(str, Pattern, IgnoreCase = TRUE, Global = TRUE) DIM re = CREATEOLEOBJ("VBScript.RegExp") re.Pattern = Pattern re.IgnoreCase = IgnoreCase re.Global = Global RESULT = re.Test(str) FEND ////////////////////////////////////////////////// // 【引数】 // JD : ユリウス日 // 【戻り値】 // 朔の日時 ////////////////////////////////////////////////// FUNCTION saku(JD) DIM lc = 1 // loop counter DIM JD1 = INT(JD) DIM JD2 = JD - JD1 JD2 = JD2 - 9/24 DIM Δt1 = 0 DIM Δt2 = 1 WHILE ABS(Δt1+Δt2) > 1/86400 DIM JC = (JD2 + 0.5) / 36525 JC = JC + (JD1 - 2451545) / 36525 DIM λsun = longitudeSun(JC) DIM λmoon = longitudeMoon(JC) DIM Δλ = λmoon - λsun SELECT TRUE CASE lc = 1 AND Δλ < 0 Δλ = normalizeAngle(Δλ) CASE λsun >= 0 AND λsun <= 20 AND λmoon >= 300 Δλ = normalizeAngle(Δλ) Δλ = 360 - Δλ CASE ABS(Δλ) > 40 Δλ = normalizeAngle(Δλ) SELEND Δt1 = INT(Δλ * 29.530589 / 360) Δt2 = Δλ * 29.530589 / 360 Δt2 = Δt2 - Δt1 JD1 = JD1 - Δt1 JD2 = JD2 - Δt2 IFB JD2 < 0 THEN JD2 = JD2 + 1 JD1 = JD1 - 1 ENDIF IFB lc = 15 AND ABS(Δt1+Δt2) > 1/86400 THEN JD1 = INT(JD - 26) JD2 = 0 ELSEIF lc > 30 AND ABS(Δt1+Δt2) > 1/86400 JD1 = JD JD2 = 0 ENDIF lc = lc + 1 WEND RESULT = JD1 + JD2 + 9/24 FEND ////////////////////////////////////////////////// // 【引数】 // inputs : 繰り返す文字列 // multiplier : inputsを繰り返す回数 // 【戻り値】 // inputsをmultiplier回を繰り返した文字列を返します ////////////////////////////////////////////////// FUNCTION strRepeat(inputs, multiplier) DIM res = "" FOR n = 1 TO multiplier res = res + inputs NEXT RESULT = res FEND ////////////////////////////////////////////////// // 【引数】 // serial : シリアル値 // format : フォーマット // 【戻り値】 // 数値を表示書式に基づいて変換した文字列 ////////////////////////////////////////////////// ////////////////////////////////////////////////// // 【引数】 // serial : シリアル値 // format : フォーマット // 【戻り値】 // ////////////////////////////////////////////////// FUNCTION text(serial, format, hour12 = FALSE) HASHTBL startDate startDate["明治"] = "1868/01/25" startDate["大正"] = "1912/07/30" startDate["昭和"] = "1926/12/25" startDate["平成"] = "1989/01/08" startDate["令和"] = "2019/05/01" DIM baseDate = "1899/12/30" serial = VAL(serial) SELECT TRUE CASE reTest(format, "\[h+\]") Matches = reExecute(format, "\[(h+)\]") DIM hour = iif(hour12, Hour(serial) MOD 12, Hour(serial)) RESULT = text(hour, strRepeat("0", LENGTH(Matches.Item(0).SubMatches(0)))) CASE reTest(format, "^h+$") Matches = reExecute(format, "^(h+)$") hour = iif(hour12, Hour(serial) MOD 12, Hour(serial)) RESULT = text(hour MOD 24, strRepeat("0", LENGTH(Matches.Item(0).SubMatches(0)))) CASE reTest(format, "\[m+\]") Matches = reExecute(format, "\[(m+)\]") RESULT = text(serial * 1440, strRepeat("0", LENGTH(Matches.Item(0).SubMatches(0)))) CASE format = "m" GETTIME(serial, baseDate) RESULT = text(G_TIME_MM, "0") CASE format = "mm" GETTIME(serial, baseDate) RESULT = G_TIME_MM2 CASE format = "n" GETTIME(serial, baseDate) RESULT = G_TIME_NN CASE format = "nn" GETTIME(serial, baseDate) RESULT = G_TIME_NN2 CASE format = "s" GETTIME(serial, baseDate) RESULT = text(G_TIME_SS, "0") CASE format = "ss" GETTIME(serial, baseDate) RESULT = G_TIME_SS2 CASE format = "yyyy" GETTIME(serial, baseDate) RESULT = G_TIME_YY4 CASE format = "yy" GETTIME(serial, baseDate) RESULT = COPY(G_TIME_YY4, 3, 2) CASE format = "e" SELECT TRUE CASE dateDiff("d", startDate["令和"], text(serial, "yyyy/mm/dd")) >= 0 RESULT = text(serial, "yyyy") - 2018 CASE dateDiff("d", startDate["平成"], text(serial, "yyyy/mm/dd")) >= 0 RESULT = text(serial, "yyyy") - 1988 CASE dateDiff("d", startDate["昭和"], text(serial, "yyyy/mm/dd")) >= 0 RESULT = text(serial, "yyyy") - 1925 CASE dateDiff("d", startDate["大正"], text(serial, "yyyy/mm/dd")) >= 0 RESULT = text(serial, "yyyy") - 1911 CASE dateDiff("d", startDate["明治"], text(serial, "yyyy/mm/dd")) >= 0 RESULT = text(serial, "yyyy") - 1867 SELEND CASE format = "ee" SELECT TRUE CASE dateDiff("d", startDate["令和"], text(serial, "yyyy/mm/dd")) >= 0 RESULT = text(text(serial, "yyyy") - 2018, "00") CASE dateDiff("d", startDate["平成"], text(serial, "yyyy/mm/dd")) >= 0 RESULT = text(text(serial, "yyyy") - 1988, "00") CASE dateDiff("d", startDate["昭和"], text(serial, "yyyy/mm/dd")) >= 0 RESULT = text(text(serial, "yyyy") - 1925, "00") CASE dateDiff("d", startDate["大正"], text(serial, "yyyy/mm/dd")) >= 0 RESULT = text(text(serial, "yyyy") - 1911, "00") CASE dateDiff("d", startDate["明治"], text(serial, "yyyy/mm/dd")) >= 0 RESULT = text(text(serial, "yyyy") - 1867, "00") SELEND CASE format = "g" SELECT TRUE CASE dateDiff("d", startDate["令和"], text(serial, "yyyy/mm/dd")) >= 0; RESULT = "R" CASE dateDiff("d", startDate["平成"], text(serial, "yyyy/mm/dd")) >= 0; RESULT = "H" CASE dateDiff("d", startDate["昭和"], text(serial, "yyyy/mm/dd")) >= 0; RESULT = "S" CASE dateDiff("d", startDate["大正"], text(serial, "yyyy/mm/dd")) >= 0; RESULT = "T" CASE dateDiff("d", startDate["明治"], text(serial, "yyyy/mm/dd")) >= 0; RESULT = "M" SELEND CASE format = "gg" RESULT = COPY(text(serial, "ggg"), 1, 1) CASE format = "ggg" SELECT TRUE CASE dateDiff("d", startDate["令和"], text(serial, "yyyy/mm/dd")) >= 0; RESULT = "令和" CASE dateDiff("d", startDate["平成"], text(serial, "yyyy/mm/dd")) >= 0; RESULT = "平成" CASE dateDiff("d", startDate["昭和"], text(serial, "yyyy/mm/dd")) >= 0; RESULT = "昭和" CASE dateDiff("d", startDate["大正"], text(serial, "yyyy/mm/dd")) >= 0; RESULT = "大正" CASE dateDiff("d", startDate["明治"], text(serial, "yyyy/mm/dd")) >= 0; RESULT = "明治" SELEND CASE format = "mmmmm" RESULT = COPY(text(serial, "mmmm"), 1, 1) CASE format = "mmmm" DIM month[] = "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" RESULT = month[text(serial, "m") - 1] CASE format = "mmm" RESULT = COPY(text(serial, "mmmm"), 1, 3) CASE format = "dd" GETTIME(serial, baseDate) RESULT = text(G_TIME_DD2, "00") CASE format = "d" GETTIME(serial, baseDate) RESULT = text(G_TIME_DD, "0") CASE reTest(format, "^[ad]{3,4}$") Matches = reExecute(format, "([ad]{3,4})") GETTIME(serial, baseDate) DIM aaa[] = "日", "月", "火", "水", "木", "金", "土" DIM aaaa[] = "日曜日", "月曜日", "火曜日", "水曜日", "木曜日", "金曜日", "土曜日" DIM ddd[] = "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" DIM dddd[] = "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"; RESULT = EVAL(Matches.Item(0).SubMatches(0) + "[" + getWeekday(G_TIME_WW, 1) + "]") CASE reTest(format, "(0+\.?0+)?%") Matches = reExecute(format, "(0+\.?0+)?%") RESULT = text(serial * 100, Matches.Item(0).SubMatches(0)) + "%" CASE reTest(format, "^\[DBNum\d{1,4}\](.*?)$") Matches = reExecute(format, "^\[DBNum(\d{1,4})\](.*?)$") DIM value = VAL(Matches.Item(0).SubMatches(0)) DIM sss = text(serial, Matches.Item(0).SubMatches(1)) Matches = reExecute(sss, "(\D+)?(\d+)(\D+)?") DIM res = "" FOR m = 0 TO Matches.Count - 1 serial = Matches.Item(m).SubMatches(1) SELECT value CASE 1, 2 DIM n[][9] = "〇", "一", "二", "三", "四", "五", "六", "七", "八", "九", + _ "", "壱", "弐", "参", "四", "伍", "六", "七", "八", "九" DIM a[][3] = "", "十", "百", "千", + _ "", "拾", "百", "阡" DIM b[][3] = "", "万", "億", "兆", + _ "", "萬", "億", "兆" DIM r = "" DIM j = 0 type = value - 1 REPEAT DIM str = "" DIM n4 = serial MOD 10000 FOR i = LENGTH(n4) TO 1 STEP -1 s = COPY(n4, i, 1) IFB s = 1 AND a[type][LENGTH(n4)-i] <> "" THEN str = IIF(s, a[type][LENGTH(n4)-i], "") + str ELSE str = n[type][s] + IIF(s, a[type][LENGTH(n4)-i], "") + str ENDIF NEXT IF str <> "" THEN r = str + b[type][j] + r j = j + 1 serial = INT(serial / 10000) UNTIL serial = 0 res = res + Matches.Item(m).SubMatches(0) + r + Matches.Item(m).SubMatches(2) CASE 3 res = res + Matches.Item(m).SubMatches(0) + STRCONV(serial, SC_FULLWIDTH) + Matches.Item(m).SubMatches(2) CASE 4 res = res + Matches.Item(m).SubMatches(0) + STRCONV(serial, SC_HALFWIDTH) + Matches.Item(m).SubMatches(2) SELEND NEXT RESULT = res CASE reTest(format, "^(.*?)(AM\/PM|am\/pm|A\/P|a\/p)(.*?)$") Matches = reExecute(format, "^(.*?)(AM\/PM|am\/pm|A\/P|a\/p)(.*?)$") DIM array = SPLIT(Matches.Item(0).SubMatches(1), "/") ampm = array[IIF(serial - INT(serial) >= 0.5, 1, 0)] hour12 = TRUE res = "" WITH Matches.Item(0) res = text(serial, .SubMatches(0), hour12) + ampm + text(serial, .SubMatches(2), hour12) ENDWITH RESULT = res CASE reTest(format, "([^ymdagehns]{0,})?(([ymdagehns])\3{0,})([^ymdagehns]+)?") Matches = reExecute(format, "([^ymdagehns]{0,})?(([ymdagehns])\3{0,})([^ymdagehns]+)?") FOR n = 0 TO Matches.Count - 1 IF n = 0 THEN res = Matches.Item(n).SubMatches(0) NEXT FOR n = 0 TO Matches.Count - 1 WITH Matches.Item(n) res = res + text(serial, .SubMatches(1), hour12) + .SubMatches(3) ENDWITH NEXT RESULT = res CASE format = "0/0" DIM separator = POS(".", serial) DIM g = 0 IFB separator <> 0 THEN DIM keta = LENGTH(serial) DIM shift = POWER(10, keta - separator) IFB shift >= POWER(10, 15) THEN DIM position = 0 FOR i = 0 TO 14 IFB serial * POWER(10, i) - serial >= 1 THEN position = i BREAK ENDIF NEXT tmp = serial * POWER(10, position) FOR i = 1 TO 15 r = (tmp * POWER(10, i)) / serial - (tmp / serial) a1 = tmp * POWER(10, i) - tmp IF a1 = INT(a1) THEN BREAK NEXT DIM frac[] = a1, r g = GCD(frac) RESULT = (a1/g) + "/" + (r/g) ELSE DIM molecule = serial * shift // 分子 DIM denominator = shift // 分母 DIM nums[] = molecule, denominator g = GCD(nums) molecule = molecule / g denominator = denominator / g RESULT = molecule + "/" + denominator ENDIF ELSE RESULT = serial + "/1" ENDIF CASE reTest(format, "(0+)\.?(0+)?") AND UBound(SPLIT(format, ".")) <= 1 Matches = reExecute(format, "(0+)\.?(0+)?") len1 = LENGTH(Matches.Item(0).SubMatches(0)) len2 = LENGTH(Matches.Item(0).SubMatches(1)) DIM arr[] = LENGTH(INT(serial)), len1 IFB POS(".", format) THEN RESULT = REPLACE(FORMAT(serial, CALCARRAY(arr, CALC_MAX) + len2 + 1, len2), " ", "0") ELSE RESULT = REPLACE(FORMAT(serial, CALCARRAY(arr, CALC_MAX)), " ", "0") ENDIF SELEND FEND ////////////////////////////////////////////////// // 【引数】 // str : 時刻文字列。hh:nn:ss AM/PM、hh:nn AM/PM、hh AM/PM、hh:nn:ss、hh:nn、hh時nn分ss秒、hh時nn分のいずれかの形式を指定。 // 【戻り値】 // シリアル値 (例)0…00:00:00、0.5…12:00:00、0.999988425925926…23:59:59 ////////////////////////////////////////////////// FUNCTION timeValue(str) DIM serial = 0 DIM Matches DIM pattern = "(\d+)" DIM hh = "(0?[0-9]|1[0-2])" DIM ampm = "([AP]M|[ap]m)" SELECT TRUE CASE reTest(str, "\b" + hh + ":" + pattern + ":" + pattern + " " + ampm + "\b") Matches = reExecute(str, "\b" + hh + ":" + pattern + ":" + pattern + " " + ampm + "\b") WITH Matches.Item(0) serial = timeValue(.SubMatches(0) + " " + .SubMatches(3)) + VAL(.SubMatches(1)) / 1440 + VAL(.SubMatches(2)) / 86400 ENDWITH CASE reTest(str, "\b" + hh + ":" + pattern + " " + ampm + "\b") Matches = reExecute(str, "\b" + hh + ":" + pattern + " " + ampm + "\b") WITH Matches.Item(0) serial = timeValue(.SubMatches(0) + " " + .SubMatches(2)) + VAL(.SubMatches(1)) / 1440 ENDWITH CASE reTest(str, "\b" + hh + " " + ampm + "\b") Matches = reExecute(str, "\b" + hh + " " + ampm + "\b") WITH Matches.Item(0) serial = VAL(.SubMatches(0) MOD 12) + IIF(reTest(.SubMatches(1), "AM|am"), 0, 12) serial = serial / 24 ENDWITH CASE reTest(str, "\b" + pattern + ":" + pattern + ":" + pattern + "\b") Matches = reExecute(str, "\b" + pattern + ":" + pattern + ":" + pattern + "\b") WITH Matches.Item(0) serial = VAL(.SubMatches(0)) / 24 + VAL(.SubMatches(1)) / 1440 + VAL(.SubMatches(2)) / 86400 ENDWITH CASE reTest(str, "\b" + pattern + ":" + pattern + "\b") Matches = reExecute(str, "\b" + pattern + ":" + pattern + "\b") WITH Matches.Item(0) serial = VAL(.SubMatches(0)) / 24 + VAL(.SubMatches(1)) / 1440 ENDWITH CASE reTest(str, "\b" + pattern + "時" + pattern + "分" + pattern + "秒") Matches = reExecute(str, "\b" + pattern + "時" + pattern + "分" + pattern + "秒") WITH Matches.Item(0) serial = VAL(.SubMatches(0)) / 24 + VAL(.SubMatches(1)) / 1440 + VAL(.SubMatches(2)) / 86400 ENDWITH CASE reTest(str, "\b" + pattern + "時" + pattern + "分") Matches = reExecute(str, "\b" + pattern + "時" + pattern + "分") WITH Matches.Item(0) serial = VAL(.SubMatches(0)) / 24 + VAL(.SubMatches(1)) / 1440 ENDWITH DEFAULT serial = ERR_VALUE SELEND RESULT = serial - INT(serial) FEND ////////////////////////////////////////////////// // 【引数】 // // 【戻り値】 // 今日の日付 ////////////////////////////////////////////////// FUNCTION today() GETTIME() RESULT = G_TIME_YY4 + "/" + G_TIME_MM2 + "/" + G_TIME_DD2 FEND ////////////////////////////////////////////////// // 【引数】 // arrayname : 上限値を求める配列の名前 // dimension : 返す次元を示す整数 // 【戻り値】 // 配列の上限値 ////////////////////////////////////////////////// FUNCTION UBound(arrayname[], dimension = 1) RESULT = EVAL("RESIZE(arrayname" + strRepeat("[0]", dimension - 1) + ")") FEND ////////////////////////////////////////////////// // 【引数】 // year : 年 // month : 月 // day : 日 // hour : 時 // minute : 分 // second : 秒 // 【戻り値】 // ユリウス日 ////////////////////////////////////////////////// FUNCTION YMDToJD(year, month, day, hour = 0, minute = 0, second = 0) year = VAL(year); month = VAL(month); day = VAL(day); hour = VAL(hour); minute = VAL(minute); second = VAL(second) IFB month < 3 THEN year = year - 1 month = month + 12 ENDIF DIM JD = INT(year * 365.25) JD = JD + INT(year / 400) JD = JD - INT(year / 100) JD = JD + INT((month - 2) * 30.59) JD = JD + 1721088 JD = JD + day DIM t = second / 3600 t = t + minute / 60 t = t + hour t = t / 24 JD = JD + t RESULT = JD FEND
結果
2022/11/1 6.7 2022/11/2 7.7 2022/11/3 8.7 2022/11/4 9.7 2022/11/5 10.7 2022/11/6 11.7 2022/11/7 12.7 2022/11/8 13.7 2022/11/9 14.7 2022/11/10 15.7 2022/11/11 16.7 2022/11/12 17.7 2022/11/13 18.7 2022/11/14 19.7 2022/11/15 20.7 2022/11/16 21.7 2022/11/17 22.7 2022/11/18 23.7 2022/11/19 24.7 2022/11/20 25.7 2022/11/21 26.7 2022/11/22 27.7 2022/11/23 28.7 2022/11/24 0.2 2022/11/25 1.2 2022/11/26 2.2 2022/11/27 3.2 2022/11/28 4.2 2022/11/29 5.2 2022/11/30 6.2
使用関数
指定した日付の直前の朔の日時を求める
DIM JD = saku(YMDToJD(2020, 4, 5)) DIM d = JDToYMD(JD) PRINT d[0] + "/" + d[1] + "/" + d[2] ////////////////////////////////////////////////// // 【引数】 // deg : 角度(度数法) // 【戻り値】 // 度数法から弧度法に変換した値 ////////////////////////////////////////////////// FUNCTION degToRad(deg) RESULT = deg * (3.14159265358979 / 180) FEND ////////////////////////////////////////////////// // 【引数】 // JD : ユリウス日 // 【戻り値】 // グレゴリオ暦を格納した配列(0 : 年, 1 : 月, 2 : 日, 3 : 時, 4 : 分, 5 : 秒) ////////////////////////////////////////////////// FUNCTION JDToYMD(JD) DIM x0 = INT(JD + 68570) DIM x1 = INT(x0 / 36524.25) DIM x2 = x0 - INT(36524.25 * x1 + 0.75) DIM x3 = INT((x2 + 1) / 365.2425) DIM x4 = x2 - INT(365.25 * x3) + 31 DIM x5 = INT(INT(x4) / 30.59) DIM x6 = INT(INT(x5) / 11) DIM t2 = x4 - INT(30.59 * x5) DIM t1 = x5 - 12 * x6 + 2 DIM t0 = 100 * (x1 - 49) + x3 + x6 IFB t1 = 2 AND t2 > 28 THEN SELECT TRUE CASE t0 MOD 100 = 0 AND t0 MOD 400 = 0 t2 = 29 CASE t0 MOD 4 = 0 t2 = 29 DEFAULT t2 = 28 SELEND ENDIF DIM tm = 86400 * (JD - INT(JD)) DIM t3 = INT(tm / 3600) DIM t4 = INT((tm - 3600 * t3) / 60) DIM t5 = INT(tm - 3600 * t3 - 60 * t4) DIM t[] = t0, t1, t2, t3, t4, t5 RESULT = SLICE(t) FEND ////////////////////////////////////////////////// // 【引数】 // JC : ユリウス世紀 // 【戻り値】 // 月黄経(λmoon) ////////////////////////////////////////////////// FUNCTION longitudeMoon(JC) DIM A[63] = 0.0003, 0.0003, 0.0003, 0.0003, 0.0003, 0.0003, 0.0003, 0.0004, 0.0004, 0.0005, 0.0005, 0.0005, 0.0006, 0.0006, 0.0007, 0.0007, 0.0007, 0.0007, 0.0008, 0.0009, 0.0011, 0.0012, 0.0016, 0.0018, 0.0021, 0.0021, 0.0021, 0.0022, 0.0023, 0.0024, 0.0026, 0.0027, 0.0028, 0.0037, 0.0038, 0.004, 0.004, 0.004, 0.005, 0.0052, 0.0068, 0.0079, 0.0085, 0.01, 0.0107, 0.011, 0.0125, 0.0154, 0.0304, 0.0347, 0.0409, 0.0458, 0.0533, 0.0571, 0.0588, 0.1144, 0.1851, 0.2136, 0.6583, 1.274, 6.2888, 481267.8809 * JC, 218.3162 DIM k[63] = 2322131, 4067, 549197, 1808933, 349472, 381404, 958465, 12006, 39871, 509131, 1745069, 1908795, 2258267, 111869, 27864, 485333, 405201, 790672, 1403732, 858602, 1920802, 1267871, 1856938, 401329, 341337, 71998, 990397, 818536, 922466, 99863, 1379739, 918399, 1934, 541062, 1781068, 133, 1844932, 1331734, 481266, 31932, 926533, 449334, 826671, 1431597, 1303870, 489205, 1443603, 75870, 513197.9, 445267.1, 441199.8, 854535.2, 1367733.1, 377336.3, 63863.5, 966404, 35999, 954397.7, 890534.2, 413335.3, 477198.9, 0, 0 DIM θ0[63] = 191, 70, 220, 58, 337, 354, 340, 187, 223, 242, 24, 90, 156, 38, 127, 186, 50, 114, 98, 129, 186, 249, 152, 274, 16, 85, 357, 151, 163, 122, 17, 182, 145, 259, 21, 29, 56, 283, 205, 107, 323, 188, 111, 315, 246, 142, 52, 41, 222.5, 27.9, 47.4, 148.2, 280.7, 13.2, 124.2, 276.5, 87.53, 179.93, 145.7, 10.74, 44.963, 0, 0 DIM λmoon[63] FOR n = 0 TO 60 DIM ang = normalizeAngle(k[n] * JC + θ0[n]) λmoon[n] = A[n] * COS(degToRad(ang)) NEXT λmoon[61] = normalizeAngle(A[61]) λmoon[62] = normalizeAngle(A[62]) RESULT = normalizeAngle(CALCARRAY(λmoon, CALC_ADD)) FEND ////////////////////////////////////////////////// // 【引数】 // JC : ユリウス世紀 // 【戻り値】 // 太陽黄経(λsun) ////////////////////////////////////////////////// FUNCTION longitudeSun(JC) DIM A[18] = 0.0004, 0.0004, 0.0005, 0.0005, 0.0006, 0.0007, 0.0007, 0.0007, 0.0013, 0.0015, 0.0018, 0.0018, 0.0020, 0.0200, -0.0048*JC, 1.9147, 36000.7695*JC, 280.4659 DIM k[18] = 31557.0, 29930.0, 2281.0, 155.0, 33718.0, 9038.0, 3035.0, 65929.0, 22519.0, 45038.0, 445267.0, 19.0, 32964.0, 71998.1, 35999.05, 35999.05, 0, 0 DIM θ0[18] = 161.0, 48.0, 221.0, 118.0, 316.0, 64.0, 110.0, 45.0, 352.0, 254.0, 208.0, 159.0, 158.0, 265.1, 267.52, 267.52, 0, 0 DIM λsun[18] FOR n = 0 TO 15 DIM ang = normalizeAngle(k[n] * JC + θ0[n]) λsun[n] = A[n] * COS(degToRad(ang)) NEXT λsun[16] = normalizeAngle(A[16]) λsun[17] = normalizeAngle(A[17]) RESULT = normalizeAngle(CALCARRAY(λsun, CALC_ADD)) FEND ////////////////////////////////////////////////// // 【引数】 // deg : 度数法 // 【戻り値】 // 度単位の角度を0~360度に正規化 ////////////////////////////////////////////////// FUNCTION normalizeAngle(deg) SELECT TRUE CASE deg >= 360 deg = deg - INT(deg / 360) * 360 CASE deg < 0 deg = deg + INT(ABS(deg / 360) + 1) * 360 SELEND RESULT = deg FEND ////////////////////////////////////////////////// // 【引数】 // JD : ユリウス日 // 【戻り値】 // 朔の日時 ////////////////////////////////////////////////// FUNCTION saku(JD) DIM lc = 1 // loop counter DIM JD1 = INT(JD) DIM JD2 = JD - JD1 JD2 = JD2 - 9/24 DIM Δt1 = 0 DIM Δt2 = 1 WHILE ABS(Δt1+Δt2) > 1/86400 DIM JC = (JD2 + 0.5) / 36525 JC = JC + (JD1 - 2451545) / 36525 DIM λsun = longitudeSun(JC) DIM λmoon = longitudeMoon(JC) DIM Δλ = λmoon - λsun SELECT TRUE CASE lc = 1 AND Δλ < 0 Δλ = normalizeAngle(Δλ) CASE λsun >= 0 AND λsun <= 20 AND λmoon >= 300 Δλ = normalizeAngle(Δλ) Δλ = 360 - Δλ CASE ABS(Δλ) > 40 Δλ = normalizeAngle(Δλ) SELEND Δt1 = INT(Δλ * 29.530589 / 360) Δt2 = Δλ * 29.530589 / 360 Δt2 = Δt2 - Δt1 JD1 = JD1 - Δt1 JD2 = JD2 - Δt2 IFB JD2 < 0 THEN JD2 = JD2 + 1 JD1 = JD1 - 1 ENDIF IFB lc = 15 AND ABS(Δt1+Δt2) > 1/86400 THEN JD1 = INT(JD - 26) JD2 = 0 ELSEIF lc > 30 AND ABS(Δt1+Δt2) > 1/86400 JD1 = JD JD2 = 0 ENDIF lc = lc + 1 WEND RESULT = JD1 + JD2 + 9/24 FEND ////////////////////////////////////////////////// // 【引数】 // year : 年 // month : 月 // day : 日 // hour : 時 // minute : 分 // second : 秒 // 【戻り値】 // ユリウス日 ////////////////////////////////////////////////// FUNCTION YMDToJD(year, month, day, hour = 0, minute = 0, second = 0) year = VAL(year); month = VAL(month); day = VAL(day); hour = VAL(hour); minute = VAL(minute); second = VAL(second) IFB month < 3 THEN year = year - 1 month = month + 12 ENDIF DIM JD = INT(year * 365.25) JD = JD + INT(year / 400) JD = JD - INT(year / 100) JD = JD + INT((month - 2) * 30.59) JD = JD + 1721088 JD = JD + day DIM t = second / 3600 t = t + minute / 60 t = t + hour t = t / 24 JD = JD + t RESULT = JD FEND
結果
2020/3/24
使用関数
今年の十五夜の日付を求める
GETTIME() DIM year = G_TIME_YY + 1 DIM month = 1 DIM day = 1 REPEAT DIM JD = saku(YMDToJD(year, month, day)) DIM d = JDToYMD(JD) year = d[0] month = d[1] day = d[2] DIM date = getKyureki(year, month, day) UNTIL date[2] = 8 RESIZE(d, 2) arrayMap("text(%val%, <#DBL>00<#DBL>)", d) date = JOIN(d, "/") PRINT dateAdd("d", 14, date) ////////////////////////////////////////////////// // 【引数】 // array : 要素を追加する配列(参照引数) // values : 追加する要素をvalue1から指定 // 【戻り値】 // 処理後の配列の要素の数 ////////////////////////////////////////////////// FUNCTION arrayPush(var array[], value1 = EMPTY, value2 = EMPTY, value3 = EMPTY, value4 = EMPTY, value5 = EMPTY, value6 = EMPTY, value7 = EMPTY, value8 = EMPTY, value9 = EMPTY, value10 = EMPTY, value11 = EMPTY, value12 = EMPTY, value13 = EMPTY, value14 = EMPTY, value15 = EMPTY, value16 = EMPTY) DIM i = 1 WHILE EVAL("value" + i) <> EMPTY DIM res = RESIZE(array, UBound(array) + 1) array[res] = EVAL("value" + i) i = i + 1 WEND RESULT = LENGTH(array) FEND ////////////////////////////////////////////////// // 【引数】 // JD : ユリウス日 // 【戻り値】 // 中気と太陽黄経を格納した配列(0 : 中気, 1 : 太陽黄経) ////////////////////////////////////////////////// FUNCTION chuki(JD) JD = JD - 9/24 DIM t = (JD + 0.5 - 2451545) / 36525 DIM λsun = longitudeSun(t) DIM λsun0 = 30 * INT(λsun/30) REPEAT t = (JD + 0.5 - 2451545) / 36525 λsun = longitudeSun(t) DIM Δλ = λsun - λsun0 SELECT TRUE CASE Δλ > 180 Δλ = Δλ - 360 CASE Δλ < -180 Δλ = Δλ + 180 SELEND DIM Δt = Δλ * 365.2 / 360 JD = JD - Δt UNTIL Δt <= 1/86400 JD = JD + 9/24 DIM arr[1] = JD, λsun RESULT = SLICE(arr) 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 ////////////////////////////////////////////////// // 【引数】 // interval : 時間単位(yyyy︰年、q:四半期、m︰月、d︰日、w:週日、ww:週、h:時、n:分、s:秒) // date1 : 日時1 // date2 : 日時2 // 【戻り値】 // date2からdate1を引いた時間間隔を求めます。 ////////////////////////////////////////////////// FUNCTION dateDiff(interval, date1, date2) DIM y1, y2, m1, m2, d1, d2, d SELECT interval CASE "yyyy" GETTIME(0, date1) y1 = G_TIME_YY GETTIME(0, date2) y2 = G_TIME_YY d = y2 - y1 CASE "q" GETTIME(0, date1) y1 = G_TIME_YY m1 = G_TIME_MM GETTIME(0, date2) y2 = G_TIME_YY m2 = G_TIME_MM d = y2 * 4 + CEIL(m2/3) - (y1 * 4 + CEIL(m1/3)) CASE "m" GETTIME(0, date1) y1 = G_TIME_YY m1 = G_TIME_MM GETTIME(0, date2) y2 = G_TIME_YY m2 = G_TIME_MM d = (y2 - y1) * 12 + m2 - m1 CASE "d" d1 = GETTIME(0, date1) d2 = GETTIME(0, date2) d = (d2 - d1) / 86400 CASE "w" d = INT(dateDiff("d", date1, date2) / 7) CASE "ww" date1 = dateAdd("d", -1 * getWeekday(date1), date1) d = INT(dateDiff("d", date1, date2) / 7) CASE "h" d = dateDiff("d", date1, date2) * 24 CASE "n" d = dateDiff("d", date1, date2) * 1440 CASE "s" d = dateDiff("d", date1, date2) * 86400 SELEND RESULT = d FEND ////////////////////////////////////////////////// // 【引数】 // deg : 角度(度数法) // 【戻り値】 // 度数法から弧度法に変換した値 ////////////////////////////////////////////////// FUNCTION degToRad(deg) RESULT = deg * (3.14159265358979 / 180) FEND ////////////////////////////////////////////////// // 【引数】 // array : 最大公約数を求める数値を格納した配列 // 【戻り値】 // 最大公約数 ////////////////////////////////////////////////// FUNCTION GCD(array[]) DIM c = LENGTH(array) DIM rem = array[c-1] MOD array[c-2] IFB rem = 0 THEN IFB LENGTH(array) = 2 THEN RESULT = array[c-2] EXIT ENDIF RESIZE(array, c-2) RESULT = GCD(array) EXIT ENDIF array[c-1] = array[c-2] array[c-2] = rem RESULT = GCD(array) 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 ////////////////////////////////////////////////// // 【引数】 // year : 年 // month : 月 // day : 日 // 【戻り値】 // 旧暦を格納した配列(0 : 年, 1 : 月, 2 : 日) ////////////////////////////////////////////////// FUNCTION getKyureki(year, month, day) DIM tm = YMDToJD(year, month, day, 0, 0, 0) DIM chu[-1] // n*2︰ユリウス日、n*2+1︰Δλsun0、n=0,1,2 DIM tmp tmp = nishiNibun(tm) FOR n = 0 TO UBound(tmp) arrayPush(chu, tmp[n]) NEXT // 中気の計算 3回 chu[n]︰n+1回目 FOR n = 0 TO 2 tmp = chuki(chu[n*2] + 32) FOR n = 0 TO UBound(tmp) arrayPush(chu, tmp[n]) NEXT NEXT DIM saku[5] saku[0] = saku(chu[0]) // 朔の計算 FOR n = 1 TO 4 saku[n] = saku(saku[n-1] + 30) IFB ABS(INT(saku[n-1]) - INT(saku[n])) <= 26 THEN saku[n] = saku(saku[n-1] + 35) ENDIF NEXT // 朔の修正 SELECT TRUE CASE saku[1] <= INT(chu[0*2+0]) SHIFTARRAY(saku, -1) saku[4] = saku(saku[3] + 35) CASE saku[0] > INT(chu[0*2+0]) SHIFTARRAY(saku, 1) saku[0] = saku(saku[0] - 27) SELEND DIM kyureki[3] // 0︰年、1︰閏月、2︰月、3︰日 // 閏月検索 DIM flg = FALSE IF INT(saku[4]) <= INT(chu[3*2+0]) THEN flg = TRUE DIM m[4][2] m[0][0] = INT(chu[0*2+1]/30) + 2 IF m[0][1] > 12 THEN m[0][0] = m[0][0] - 12 m[0][2] = INT(saku[0*0+0]) m[0][1] = "" FOR n = 1 TO 4 IFB flg = TRUE AND n <> 1 THEN IFB INT(chu[(n-1)*2+0]) <= INT(saku[n-1]) OR INT(chu[(n-1)*2+0]) >= INT(saku[n]) THEN m[n-1][0] = m[n-2][0] m[n-1][1] = "閏" m[n-1][2] = INT(saku[n-1]) flg = FALSE ENDIF ENDIF m[n][0] = m[n-1][0] + 1 IF m[n][0] > 12 THEN m[n][0] = m[n][0] - 12 m[n][2] = INT(saku[n]) m[n][1] = "" NEXT DIM state = 0 FOR n = 0 TO 4 IFB INT(tm) < INT(m[n][2]) THEN state = 1 BREAK ELSEIF INT(tm) = INT(m[n][2]) THEN state = 2 BREAK ENDIF NEXT IF state = 0 OR state = 1 THEN n = n - 1 DIM kyureki[3] kyureki[1] = m[n][1] kyureki[2] = m[n][0] kyureki[3] = INT(tm) - INT(m[n][2]) + 1 d = JDToYMD(tm) kyureki[0] = d[0] IF kyureki[2] > 9 AND kyureki[2] > d[1] THEN kyureki[0] = kyureki[0] - 1 RESULT = SLICE(kyureki) FEND ////////////////////////////////////////////////// // 【引数】 // date : 日付文字列(”YYYYMMDD” or “YYYY/MM/DD” or “YYYY-MM-DD” or “YYYYMMDDHHNNSS” or “YYYY/MM/DD HH:NN:SS”)もしくはシリアル値 // type : 取得する曜日番号の種類を示す0〜3または11〜17の値。1と17は日曜日を1、2と11は月曜日を1とカウントします。11以降はExcel2010で追加された値で、互換性を保つために重複した値があります。 // 【戻り値】 // typeで指定した種類によって以下の値を返します。 : (0 : 0(日曜)〜6(土曜)、1 : 1(日曜)~7(土曜)、2 : 1(月曜)~7(日曜)、3 : 0(月曜)〜6(日曜)、11 : 1(月曜)~7(日曜)、12 : 1(火曜)~7(月曜)、13 : 1(水曜)~7(火曜)、14 : 1(木曜)~7(水曜)、15 : 1(金曜)~7(木曜)、16 : 1(土曜)~7(金曜)、17 : 1(日曜)~7(土曜)) ////////////////////////////////////////////////// FUNCTION getWeekday(date, type = 1) IF VARTYPE(date) <> 258 THEN date = text(date, "yyyy/mm/dd") GETTIME(0, date) DIM w = G_TIME_WW SELECT TRUE CASE type = 0 RESULT = w CASE type = 1 RESULT = w + 1 CASE type = 2 RESULT = IIF(w=0, 7, w) CASE type = 3 RESULT = (w+6) MOD 7 CASE type >= 11 RESULT = ((getWeekday(date, 2) + 17 - type) MOD 7) + 1 SELEND FEND ////////////////////////////////////////////////// // 【引数】 // serial : シリアル値もしくは時刻文字列 // 【戻り値】 // 時刻から時間を表す0〜23の範囲の値 ////////////////////////////////////////////////// FUNCTION Hour(serial) IF VARTYPE(serial) = 258 THEN serial = timeValue(serial) RESULT = INT(serial * 24) MOD 24 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 ////////////////////////////////////////////////// // 【引数】 // JD : ユリウス日 // 【戻り値】 // グレゴリオ暦を格納した配列(0 : 年, 1 : 月, 2 : 日, 3 : 時, 4 : 分, 5 : 秒) ////////////////////////////////////////////////// FUNCTION JDToYMD(JD) DIM x0 = INT(JD + 68570) DIM x1 = INT(x0 / 36524.25) DIM x2 = x0 - INT(36524.25 * x1 + 0.75) DIM x3 = INT((x2 + 1) / 365.2425) DIM x4 = x2 - INT(365.25 * x3) + 31 DIM x5 = INT(INT(x4) / 30.59) DIM x6 = INT(INT(x5) / 11) DIM t2 = x4 - INT(30.59 * x5) DIM t1 = x5 - 12 * x6 + 2 DIM t0 = 100 * (x1 - 49) + x3 + x6 IFB t1 = 2 AND t2 > 28 THEN SELECT TRUE CASE t0 MOD 100 = 0 AND t0 MOD 400 = 0 t2 = 29 CASE t0 MOD 4 = 0 t2 = 29 DEFAULT t2 = 28 SELEND ENDIF DIM tm = 86400 * (JD - INT(JD)) DIM t3 = INT(tm / 3600) DIM t4 = INT((tm - 3600 * t3) / 60) DIM t5 = INT(tm - 3600 * t3 - 60 * t4) DIM t[] = t0, t1, t2, t3, t4, t5 RESULT = SLICE(t) FEND ////////////////////////////////////////////////// // 【引数】 // JC : ユリウス世紀 // 【戻り値】 // 月黄経(λmoon) ////////////////////////////////////////////////// FUNCTION longitudeMoon(JC) DIM A[63] = 0.0003, 0.0003, 0.0003, 0.0003, 0.0003, 0.0003, 0.0003, 0.0004, 0.0004, 0.0005, 0.0005, 0.0005, 0.0006, 0.0006, 0.0007, 0.0007, 0.0007, 0.0007, 0.0008, 0.0009, 0.0011, 0.0012, 0.0016, 0.0018, 0.0021, 0.0021, 0.0021, 0.0022, 0.0023, 0.0024, 0.0026, 0.0027, 0.0028, 0.0037, 0.0038, 0.004, 0.004, 0.004, 0.005, 0.0052, 0.0068, 0.0079, 0.0085, 0.01, 0.0107, 0.011, 0.0125, 0.0154, 0.0304, 0.0347, 0.0409, 0.0458, 0.0533, 0.0571, 0.0588, 0.1144, 0.1851, 0.2136, 0.6583, 1.274, 6.2888, 481267.8809 * JC, 218.3162 DIM k[63] = 2322131, 4067, 549197, 1808933, 349472, 381404, 958465, 12006, 39871, 509131, 1745069, 1908795, 2258267, 111869, 27864, 485333, 405201, 790672, 1403732, 858602, 1920802, 1267871, 1856938, 401329, 341337, 71998, 990397, 818536, 922466, 99863, 1379739, 918399, 1934, 541062, 1781068, 133, 1844932, 1331734, 481266, 31932, 926533, 449334, 826671, 1431597, 1303870, 489205, 1443603, 75870, 513197.9, 445267.1, 441199.8, 854535.2, 1367733.1, 377336.3, 63863.5, 966404, 35999, 954397.7, 890534.2, 413335.3, 477198.9, 0, 0 DIM θ0[63] = 191, 70, 220, 58, 337, 354, 340, 187, 223, 242, 24, 90, 156, 38, 127, 186, 50, 114, 98, 129, 186, 249, 152, 274, 16, 85, 357, 151, 163, 122, 17, 182, 145, 259, 21, 29, 56, 283, 205, 107, 323, 188, 111, 315, 246, 142, 52, 41, 222.5, 27.9, 47.4, 148.2, 280.7, 13.2, 124.2, 276.5, 87.53, 179.93, 145.7, 10.74, 44.963, 0, 0 DIM λmoon[63] FOR n = 0 TO 60 DIM ang = normalizeAngle(k[n] * JC + θ0[n]) λmoon[n] = A[n] * COS(degToRad(ang)) NEXT λmoon[61] = normalizeAngle(A[61]) λmoon[62] = normalizeAngle(A[62]) RESULT = normalizeAngle(CALCARRAY(λmoon, CALC_ADD)) FEND ////////////////////////////////////////////////// // 【引数】 // JC : ユリウス世紀 // 【戻り値】 // 太陽黄経(λsun) ////////////////////////////////////////////////// FUNCTION longitudeSun(JC) DIM A[18] = 0.0004, 0.0004, 0.0005, 0.0005, 0.0006, 0.0007, 0.0007, 0.0007, 0.0013, 0.0015, 0.0018, 0.0018, 0.0020, 0.0200, -0.0048*JC, 1.9147, 36000.7695*JC, 280.4659 DIM k[18] = 31557.0, 29930.0, 2281.0, 155.0, 33718.0, 9038.0, 3035.0, 65929.0, 22519.0, 45038.0, 445267.0, 19.0, 32964.0, 71998.1, 35999.05, 35999.05, 0, 0 DIM θ0[18] = 161.0, 48.0, 221.0, 118.0, 316.0, 64.0, 110.0, 45.0, 352.0, 254.0, 208.0, 159.0, 158.0, 265.1, 267.52, 267.52, 0, 0 DIM λsun[18] FOR n = 0 TO 15 DIM ang = normalizeAngle(k[n] * JC + θ0[n]) λsun[n] = A[n] * COS(degToRad(ang)) NEXT λsun[16] = normalizeAngle(A[16]) λsun[17] = normalizeAngle(A[17]) RESULT = normalizeAngle(CALCARRAY(λsun, CALC_ADD)) FEND ////////////////////////////////////////////////// // 【引数】 // JD : ユリウス日 // 【戻り値】 // 指定したユリウス日の直前の二至二分の日時 ////////////////////////////////////////////////// FUNCTION nishiNibun(JD) // ユリウス日を力学時に変換 DIM TD = JD - 9/24 DIM n = 1 REPEAT // 力学時をユリウス世紀に変換 DIM JC = (TD + 0.5 - 2451545) / 36525 DIM λsun = longitudeSun(JC) IF n = 1 THEN DIM λsun0 = INT(λsun / 90) * 90 DIM Δλ = λsun - λsun0 SELECT TRUE CASE Δλ > 180 Δλ = Δλ - 360 CASE Δλ < -180 Δλ = Δλ + 180 SELEND DIM Δt = Δλ * (365.2/360) TD = TD - Δt n = n + 1 UNTIL ABS(Δt) <= 1/86400 DIM arr[1] arr[0] = TD + 9/24 arr[1] = λsun0 RESULT = SLICE(arr) FEND ////////////////////////////////////////////////// // 【引数】 // deg : 度数法 // 【戻り値】 // 度単位の角度を0~360度に正規化 ////////////////////////////////////////////////// FUNCTION normalizeAngle(deg) SELECT TRUE CASE deg >= 360 deg = deg - INT(deg / 360) * 360 CASE deg < 0 deg = deg + INT(ABS(deg / 360) + 1) * 360 SELEND RESULT = deg FEND ////////////////////////////////////////////////// // 【引数】 // str : 正規表現による検索の対象となる文字列 // Pattern : 正規表現で使用するパターンを設定 // IgnoreCase : 大文字・小文字を区別しない場合はTrue、区別する場合はFalse // Global : 文字列全体を検索する場合はTrue、しない場合はFalse // 【戻り値】 // 正規表現で検索した結果をMatchesコレクションとして返します。 ////////////////////////////////////////////////// FUNCTION reExecute(str, Pattern, IgnoreCase = TRUE, Global = TRUE) DIM re = CREATEOLEOBJ("VBScript.RegExp") re.Pattern = Pattern re.IgnoreCase = IgnoreCase re.Global = Global RESULT = re.Execute(str) FEND ////////////////////////////////////////////////// // 【引数】 // str : 正規表現による検索の対象となる文字列 // Pattern : 正規表現で使用するパターンを設定 // IgnoreCase : 大文字・小文字を区別しない場合はTrue、区別する場合はFalse // Global : 文字列全体を検索する場合はTrue、しない場合はFalse // 【戻り値】 // 正規表現にマッチするかどうかを示すブール値 ////////////////////////////////////////////////// FUNCTION reTest(str, Pattern, IgnoreCase = TRUE, Global = TRUE) DIM re = CREATEOLEOBJ("VBScript.RegExp") re.Pattern = Pattern re.IgnoreCase = IgnoreCase re.Global = Global RESULT = re.Test(str) FEND ////////////////////////////////////////////////// // 【引数】 // JD : ユリウス日 // 【戻り値】 // 朔の日時 ////////////////////////////////////////////////// FUNCTION saku(JD) DIM lc = 1 // loop counter DIM JD1 = INT(JD) DIM JD2 = JD - JD1 JD2 = JD2 - 9/24 DIM Δt1 = 0 DIM Δt2 = 1 WHILE ABS(Δt1+Δt2) > 1/86400 DIM JC = (JD2 + 0.5) / 36525 JC = JC + (JD1 - 2451545) / 36525 DIM λsun = longitudeSun(JC) DIM λmoon = longitudeMoon(JC) DIM Δλ = λmoon - λsun SELECT TRUE CASE lc = 1 AND Δλ < 0 Δλ = normalizeAngle(Δλ) CASE λsun >= 0 AND λsun <= 20 AND λmoon >= 300 Δλ = normalizeAngle(Δλ) Δλ = 360 - Δλ CASE ABS(Δλ) > 40 Δλ = normalizeAngle(Δλ) SELEND Δt1 = INT(Δλ * 29.530589 / 360) Δt2 = Δλ * 29.530589 / 360 Δt2 = Δt2 - Δt1 JD1 = JD1 - Δt1 JD2 = JD2 - Δt2 IFB JD2 < 0 THEN JD2 = JD2 + 1 JD1 = JD1 - 1 ENDIF IFB lc = 15 AND ABS(Δt1+Δt2) > 1/86400 THEN JD1 = INT(JD - 26) JD2 = 0 ELSEIF lc > 30 AND ABS(Δt1+Δt2) > 1/86400 JD1 = JD JD2 = 0 ENDIF lc = lc + 1 WEND RESULT = JD1 + JD2 + 9/24 FEND ////////////////////////////////////////////////// // 【引数】 // inputs : 繰り返す文字列 // multiplier : inputsを繰り返す回数 // 【戻り値】 // inputsをmultiplier回を繰り返した文字列を返します ////////////////////////////////////////////////// FUNCTION strRepeat(inputs, multiplier) DIM res = "" FOR n = 1 TO multiplier res = res + inputs NEXT RESULT = res FEND ////////////////////////////////////////////////// // 【引数】 // serial : シリアル値 // format : フォーマット // 【戻り値】 // 数値を表示書式に基づいて変換した文字列 ////////////////////////////////////////////////// ////////////////////////////////////////////////// // 【引数】 // serial : シリアル値 // format : フォーマット // 【戻り値】 // ////////////////////////////////////////////////// FUNCTION text(serial, format, hour12 = FALSE) HASHTBL startDate startDate["明治"] = "1868/01/25" startDate["大正"] = "1912/07/30" startDate["昭和"] = "1926/12/25" startDate["平成"] = "1989/01/08" startDate["令和"] = "2019/05/01" DIM baseDate = "1899/12/30" serial = VAL(serial) SELECT TRUE CASE reTest(format, "\[h+\]") Matches = reExecute(format, "\[(h+)\]") DIM hour = iif(hour12, Hour(serial) MOD 12, Hour(serial)) RESULT = text(hour, strRepeat("0", LENGTH(Matches.Item(0).SubMatches(0)))) CASE reTest(format, "^h+$") Matches = reExecute(format, "^(h+)$") hour = iif(hour12, Hour(serial) MOD 12, Hour(serial)) RESULT = text(hour MOD 24, strRepeat("0", LENGTH(Matches.Item(0).SubMatches(0)))) CASE reTest(format, "\[m+\]") Matches = reExecute(format, "\[(m+)\]") RESULT = text(serial * 1440, strRepeat("0", LENGTH(Matches.Item(0).SubMatches(0)))) CASE format = "m" GETTIME(serial, baseDate) RESULT = text(G_TIME_MM, "0") CASE format = "mm" GETTIME(serial, baseDate) RESULT = G_TIME_MM2 CASE format = "n" GETTIME(serial, baseDate) RESULT = G_TIME_NN CASE format = "nn" GETTIME(serial, baseDate) RESULT = G_TIME_NN2 CASE format = "s" GETTIME(serial, baseDate) RESULT = text(G_TIME_SS, "0") CASE format = "ss" GETTIME(serial, baseDate) RESULT = G_TIME_SS2 CASE format = "yyyy" GETTIME(serial, baseDate) RESULT = G_TIME_YY4 CASE format = "yy" GETTIME(serial, baseDate) RESULT = COPY(G_TIME_YY4, 3, 2) CASE format = "e" SELECT TRUE CASE dateDiff("d", startDate["令和"], text(serial, "yyyy/mm/dd")) >= 0 RESULT = text(serial, "yyyy") - 2018 CASE dateDiff("d", startDate["平成"], text(serial, "yyyy/mm/dd")) >= 0 RESULT = text(serial, "yyyy") - 1988 CASE dateDiff("d", startDate["昭和"], text(serial, "yyyy/mm/dd")) >= 0 RESULT = text(serial, "yyyy") - 1925 CASE dateDiff("d", startDate["大正"], text(serial, "yyyy/mm/dd")) >= 0 RESULT = text(serial, "yyyy") - 1911 CASE dateDiff("d", startDate["明治"], text(serial, "yyyy/mm/dd")) >= 0 RESULT = text(serial, "yyyy") - 1867 SELEND CASE format = "ee" SELECT TRUE CASE dateDiff("d", startDate["令和"], text(serial, "yyyy/mm/dd")) >= 0 RESULT = text(text(serial, "yyyy") - 2018, "00") CASE dateDiff("d", startDate["平成"], text(serial, "yyyy/mm/dd")) >= 0 RESULT = text(text(serial, "yyyy") - 1988, "00") CASE dateDiff("d", startDate["昭和"], text(serial, "yyyy/mm/dd")) >= 0 RESULT = text(text(serial, "yyyy") - 1925, "00") CASE dateDiff("d", startDate["大正"], text(serial, "yyyy/mm/dd")) >= 0 RESULT = text(text(serial, "yyyy") - 1911, "00") CASE dateDiff("d", startDate["明治"], text(serial, "yyyy/mm/dd")) >= 0 RESULT = text(text(serial, "yyyy") - 1867, "00") SELEND CASE format = "g" SELECT TRUE CASE dateDiff("d", startDate["令和"], text(serial, "yyyy/mm/dd")) >= 0; RESULT = "R" CASE dateDiff("d", startDate["平成"], text(serial, "yyyy/mm/dd")) >= 0; RESULT = "H" CASE dateDiff("d", startDate["昭和"], text(serial, "yyyy/mm/dd")) >= 0; RESULT = "S" CASE dateDiff("d", startDate["大正"], text(serial, "yyyy/mm/dd")) >= 0; RESULT = "T" CASE dateDiff("d", startDate["明治"], text(serial, "yyyy/mm/dd")) >= 0; RESULT = "M" SELEND CASE format = "gg" RESULT = COPY(text(serial, "ggg"), 1, 1) CASE format = "ggg" SELECT TRUE CASE dateDiff("d", startDate["令和"], text(serial, "yyyy/mm/dd")) >= 0; RESULT = "令和" CASE dateDiff("d", startDate["平成"], text(serial, "yyyy/mm/dd")) >= 0; RESULT = "平成" CASE dateDiff("d", startDate["昭和"], text(serial, "yyyy/mm/dd")) >= 0; RESULT = "昭和" CASE dateDiff("d", startDate["大正"], text(serial, "yyyy/mm/dd")) >= 0; RESULT = "大正" CASE dateDiff("d", startDate["明治"], text(serial, "yyyy/mm/dd")) >= 0; RESULT = "明治" SELEND CASE format = "mmmmm" RESULT = COPY(text(serial, "mmmm"), 1, 1) CASE format = "mmmm" DIM month[] = "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" RESULT = month[text(serial, "m") - 1] CASE format = "mmm" RESULT = COPY(text(serial, "mmmm"), 1, 3) CASE format = "dd" GETTIME(serial, baseDate) RESULT = text(G_TIME_DD2, "00") CASE format = "d" GETTIME(serial, baseDate) RESULT = text(G_TIME_DD, "0") CASE reTest(format, "^[ad]{3,4}$") Matches = reExecute(format, "([ad]{3,4})") GETTIME(serial, baseDate) DIM aaa[] = "日", "月", "火", "水", "木", "金", "土" DIM aaaa[] = "日曜日", "月曜日", "火曜日", "水曜日", "木曜日", "金曜日", "土曜日" DIM ddd[] = "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" DIM dddd[] = "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"; RESULT = EVAL(Matches.Item(0).SubMatches(0) + "[" + getWeekday(G_TIME_WW, 1) + "]") CASE reTest(format, "(0+\.?0+)?%") Matches = reExecute(format, "(0+\.?0+)?%") RESULT = text(serial * 100, Matches.Item(0).SubMatches(0)) + "%" CASE reTest(format, "^\[DBNum\d{1,4}\](.*?)$") Matches = reExecute(format, "^\[DBNum(\d{1,4})\](.*?)$") DIM value = VAL(Matches.Item(0).SubMatches(0)) DIM sss = text(serial, Matches.Item(0).SubMatches(1)) Matches = reExecute(sss, "(\D+)?(\d+)(\D+)?") DIM res = "" FOR m = 0 TO Matches.Count - 1 serial = Matches.Item(m).SubMatches(1) SELECT value CASE 1, 2 DIM n[][9] = "〇", "一", "二", "三", "四", "五", "六", "七", "八", "九", + _ "", "壱", "弐", "参", "四", "伍", "六", "七", "八", "九" DIM a[][3] = "", "十", "百", "千", + _ "", "拾", "百", "阡" DIM b[][3] = "", "万", "億", "兆", + _ "", "萬", "億", "兆" DIM r = "" DIM j = 0 type = value - 1 REPEAT DIM str = "" DIM n4 = serial MOD 10000 FOR i = LENGTH(n4) TO 1 STEP -1 s = COPY(n4, i, 1) IFB s = 1 AND a[type][LENGTH(n4)-i] <> "" THEN str = IIF(s, a[type][LENGTH(n4)-i], "") + str ELSE str = n[type][s] + IIF(s, a[type][LENGTH(n4)-i], "") + str ENDIF NEXT IF str <> "" THEN r = str + b[type][j] + r j = j + 1 serial = INT(serial / 10000) UNTIL serial = 0 res = res + Matches.Item(m).SubMatches(0) + r + Matches.Item(m).SubMatches(2) CASE 3 res = res + Matches.Item(m).SubMatches(0) + STRCONV(serial, SC_FULLWIDTH) + Matches.Item(m).SubMatches(2) CASE 4 res = res + Matches.Item(m).SubMatches(0) + STRCONV(serial, SC_HALFWIDTH) + Matches.Item(m).SubMatches(2) SELEND NEXT RESULT = res CASE reTest(format, "^(.*?)(AM\/PM|am\/pm|A\/P|a\/p)(.*?)$") Matches = reExecute(format, "^(.*?)(AM\/PM|am\/pm|A\/P|a\/p)(.*?)$") DIM array = SPLIT(Matches.Item(0).SubMatches(1), "/") ampm = array[IIF(serial - INT(serial) >= 0.5, 1, 0)] hour12 = TRUE res = "" WITH Matches.Item(0) res = text(serial, .SubMatches(0), hour12) + ampm + text(serial, .SubMatches(2), hour12) ENDWITH RESULT = res CASE reTest(format, "([^ymdagehns]{0,})?(([ymdagehns])\3{0,})([^ymdagehns]+)?") Matches = reExecute(format, "([^ymdagehns]{0,})?(([ymdagehns])\3{0,})([^ymdagehns]+)?") FOR n = 0 TO Matches.Count - 1 IF n = 0 THEN res = Matches.Item(n).SubMatches(0) NEXT FOR n = 0 TO Matches.Count - 1 WITH Matches.Item(n) res = res + text(serial, .SubMatches(1), hour12) + .SubMatches(3) ENDWITH NEXT RESULT = res CASE format = "0/0" DIM separator = POS(".", serial) DIM g = 0 IFB separator <> 0 THEN DIM keta = LENGTH(serial) DIM shift = POWER(10, keta - separator) IFB shift >= POWER(10, 15) THEN DIM position = 0 FOR i = 0 TO 14 IFB serial * POWER(10, i) - serial >= 1 THEN position = i BREAK ENDIF NEXT tmp = serial * POWER(10, position) FOR i = 1 TO 15 r = (tmp * POWER(10, i)) / serial - (tmp / serial) a1 = tmp * POWER(10, i) - tmp IF a1 = INT(a1) THEN BREAK NEXT DIM frac[] = a1, r g = GCD(frac) RESULT = (a1/g) + "/" + (r/g) ELSE DIM molecule = serial * shift // 分子 DIM denominator = shift // 分母 DIM nums[] = molecule, denominator g = GCD(nums) molecule = molecule / g denominator = denominator / g RESULT = molecule + "/" + denominator ENDIF ELSE RESULT = serial + "/1" ENDIF CASE reTest(format, "(0+)\.?(0+)?") AND UBound(SPLIT(format, ".")) <= 1 Matches = reExecute(format, "(0+)\.?(0+)?") len1 = LENGTH(Matches.Item(0).SubMatches(0)) len2 = LENGTH(Matches.Item(0).SubMatches(1)) DIM arr[] = LENGTH(INT(serial)), len1 IFB POS(".", format) THEN RESULT = REPLACE(FORMAT(serial, CALCARRAY(arr, CALC_MAX) + len2 + 1, len2), " ", "0") ELSE RESULT = REPLACE(FORMAT(serial, CALCARRAY(arr, CALC_MAX)), " ", "0") ENDIF SELEND FEND ////////////////////////////////////////////////// // 【引数】 // str : 時刻文字列。hh:nn:ss AM/PM、hh:nn AM/PM、hh AM/PM、hh:nn:ss、hh:nn、hh時nn分ss秒、hh時nn分のいずれかの形式を指定。 // 【戻り値】 // シリアル値 (例)0…00:00:00、0.5…12:00:00、0.999988425925926…23:59:59 ////////////////////////////////////////////////// FUNCTION timeValue(str) DIM serial = 0 DIM Matches DIM pattern = "(\d+)" DIM hh = "(0?[0-9]|1[0-2])" DIM ampm = "([AP]M|[ap]m)" SELECT TRUE CASE reTest(str, "\b" + hh + ":" + pattern + ":" + pattern + " " + ampm + "\b") Matches = reExecute(str, "\b" + hh + ":" + pattern + ":" + pattern + " " + ampm + "\b") WITH Matches.Item(0) serial = timeValue(.SubMatches(0) + " " + .SubMatches(3)) + VAL(.SubMatches(1)) / 1440 + VAL(.SubMatches(2)) / 86400 ENDWITH CASE reTest(str, "\b" + hh + ":" + pattern + " " + ampm + "\b") Matches = reExecute(str, "\b" + hh + ":" + pattern + " " + ampm + "\b") WITH Matches.Item(0) serial = timeValue(.SubMatches(0) + " " + .SubMatches(2)) + VAL(.SubMatches(1)) / 1440 ENDWITH CASE reTest(str, "\b" + hh + " " + ampm + "\b") Matches = reExecute(str, "\b" + hh + " " + ampm + "\b") WITH Matches.Item(0) serial = VAL(.SubMatches(0) MOD 12) + IIF(reTest(.SubMatches(1), "AM|am"), 0, 12) serial = serial / 24 ENDWITH CASE reTest(str, "\b" + pattern + ":" + pattern + ":" + pattern + "\b") Matches = reExecute(str, "\b" + pattern + ":" + pattern + ":" + pattern + "\b") WITH Matches.Item(0) serial = VAL(.SubMatches(0)) / 24 + VAL(.SubMatches(1)) / 1440 + VAL(.SubMatches(2)) / 86400 ENDWITH CASE reTest(str, "\b" + pattern + ":" + pattern + "\b") Matches = reExecute(str, "\b" + pattern + ":" + pattern + "\b") WITH Matches.Item(0) serial = VAL(.SubMatches(0)) / 24 + VAL(.SubMatches(1)) / 1440 ENDWITH CASE reTest(str, "\b" + pattern + "時" + pattern + "分" + pattern + "秒") Matches = reExecute(str, "\b" + pattern + "時" + pattern + "分" + pattern + "秒") WITH Matches.Item(0) serial = VAL(.SubMatches(0)) / 24 + VAL(.SubMatches(1)) / 1440 + VAL(.SubMatches(2)) / 86400 ENDWITH CASE reTest(str, "\b" + pattern + "時" + pattern + "分") Matches = reExecute(str, "\b" + pattern + "時" + pattern + "分") WITH Matches.Item(0) serial = VAL(.SubMatches(0)) / 24 + VAL(.SubMatches(1)) / 1440 ENDWITH DEFAULT serial = ERR_VALUE SELEND RESULT = serial - INT(serial) FEND ////////////////////////////////////////////////// // 【引数】 // arrayname : 上限値を求める配列の名前 // dimension : 返す次元を示す整数 // 【戻り値】 // 配列の上限値 ////////////////////////////////////////////////// FUNCTION UBound(arrayname[], dimension = 1) RESULT = EVAL("RESIZE(arrayname" + strRepeat("[0]", dimension - 1) + ")") FEND ////////////////////////////////////////////////// // 【引数】 // year : 年 // month : 月 // day : 日 // hour : 時 // minute : 分 // second : 秒 // 【戻り値】 // ユリウス日 ////////////////////////////////////////////////// FUNCTION YMDToJD(year, month, day, hour = 0, minute = 0, second = 0) year = VAL(year); month = VAL(month); day = VAL(day); hour = VAL(hour); minute = VAL(minute); second = VAL(second) IFB month < 3 THEN year = year - 1 month = month + 12 ENDIF DIM JD = INT(year * 365.25) JD = JD + INT(year / 400) JD = JD - INT(year / 100) JD = JD + INT((month - 2) * 30.59) JD = JD + 1721088 JD = JD + day DIM t = second / 3600 t = t + minute / 60 t = t + hour t = t / 24 JD = JD + t RESULT = JD FEND
結果
2020/10/01
使用関数
朔
朔とは、月と太陽の黄経が等しくなる時刻のことを言い新月と同じような意味合いです。旧暦では朔を含む日を朔日としていて、この関数ではその朔を求めています。
関連記事
- YMDToJD関数 (自作関数)
- グレゴリオ暦をユリウス日に変換します。
- JDToYMD関数 (自作関数)
- ユリウス日をグレゴリオ暦に変換します。
- getKyureki関数 (自作関数)
- 西暦から旧暦を求めます。
- chuki関数 (自作関数)
- 指定したユリウス日の直前の中気を求めます。