getKyureki

引数に指定した日付から旧暦を求めます。

構文
getKyureki( year, month, day )
引数
year
month
day
戻値
旧暦を格納した配列(0 : 年, 1 : 月, 2 : 日)

プログラム

//////////////////////////////////////////////////
// 【引数】
//   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
//////////////////////////////////////////////////
// 【引数】
//   array : 要素を追加する配列(参照引数) 
//   str : 追加する要素 
// 【戻値】
//   処理後の配列の中の要素の数 
//////////////////////////////////////////////////
FUNCTION arrayPush(var arr[], str)
DIM res = RESIZE(arr, UBound(arr) + 1)
arr[res] = str
RESULT = res + 1
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
//////////////////////////////////////////////////
// 【引数】
//   deg : 度数法 
// 【戻値】
//   度数法から弧度法に変換した値 
//////////////////////////////////////////////////
FUNCTION degToRad(deg)
DIM pi = 3.14159265358979
RESULT = deg * pi / 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
//////////////////////////////////////////////////
// 【引数】
//   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
//////////////////////////////////////////////////
// 【引数】
//   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
//////////////////////////////////////////////////
// 【引数】
//   配列 : 上限値を求める配列 
// 【戻値】
//   配列の上限値 
//////////////////////////////////////////////////
FUNCTION UBound(array[])
RESULT = RESIZE(array)
FEND
//////////////////////////////////////////////////
// 【引数】
//   year : 年 
//   month : 月 
//   day : 日 
//   hour : 時 
//   minute : 分 
//   second : 秒 
// 【戻値】
//   ユリウス日 
//////////////////////////////////////////////////
FUNCTION YMDToJD(year, month, day, hour = 0, minute = 0, second = 0)
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

旧暦

ここでいう旧暦とは、現在使われているグレゴリオ暦の一つ前の天保暦のことです。天保15年1月1日(1844年2月18日)から明治5年12月2日(1872年12月31日)まで約29年間使用された。

季節 二十四節気 太陽黄経
1月節 立春りっしゅん 315度
1月中 雨水うすい 330度
2月節 啓蟄けいちつ 345度
2月中 春分しゅんぶん 0度
3月節 清明せいめい 15度
3月中 穀雨こくう 30度
4月節 立夏りっか 45度
4月中 小満しょうまん 60度
5月節 芒種ぼうしゅ 75度
5月中 夏至げし 90度
6月節 小暑しょうしょ 105度
6月中 大暑たいしょ 120度
7月節 立秋りっしゅう 135度
7月中 処暑しょしょ 150度
8月節 白露はくろ 165度
8月中 秋分しゅうぶん 180度
9月節 寒露かんろ 195度
9月中 霜降そうこう 210度
10月節 立冬りっとう 225度
10月中 小雪しょうせつ 240度
11月節 大雪たいせつ 255度
11月中 冬至とうじ 270度
12月節 小寒しょうかん 285度
12月中 大寒だいかん 300度

旧暦2033年問題

旧暦2033年問題とは、西暦2033年秋から2034年春にかけて日本の旧暦の月名が天保暦の暦法で決定できなくなる問題のことです。

プログラム実行例

旧暦を求める

2020年3月14日の旧暦を求める。

DIM d = getKyureki(2020, 3, 14)
PRINT d[0] + "/" + d[1] + d[2] + "/" + d[3]
//////////////////////////////////////////////////
// 【引数】
//   array : 要素を追加する配列(参照引数) 
//   str : 追加する要素 
// 【戻値】
//   処理後の配列の中の要素の数 
//////////////////////////////////////////////////
FUNCTION arrayPush(var arr[], str)
DIM res = RESIZE(arr, UBound(arr) + 1)
arr[res] = str
RESULT = res + 1
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
//////////////////////////////////////////////////
// 【引数】
//   deg : 度数法 
// 【戻値】
//   度数法から弧度法に変換した値 
//////////////////////////////////////////////////
FUNCTION degToRad(deg)
DIM pi = 3.14159265358979
RESULT = deg * pi / 180
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
//////////////////////////////////////////////////
// 【引数】
//   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
//////////////////////////////////////////////////
// 【引数】
//   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
//////////////////////////////////////////////////
// 【引数】
//   配列 : 上限値を求める配列 
// 【戻値】
//   配列の上限値 
//////////////////////////////////////////////////
FUNCTION UBound(array[])
RESULT = RESIZE(array)
FEND
//////////////////////////////////////////////////
// 【引数】
//   year : 年 
//   month : 月 
//   day : 日 
//   hour : 時 
//   minute : 分 
//   second : 秒 
// 【戻値】
//   ユリウス日 
//////////////////////////////////////////////////
FUNCTION YMDToJD(year, month, day, hour = 0, minute = 0, second = 0)
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/2/20

今年の十五夜の日付を求める

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)
//////////////////////////////////////////////////
// 【引数】
//   callback : 配列の各要素に適用するコールバック関数 
//   array : コールバック関数を適用する配列 
// 【戻値】
//   callback関数を適用した後、 適用後の要素を含む配列 
//////////////////////////////////////////////////
PROCEDURE arrayMap(callback, var array[])
DIM tmp[RESIZE(array)]
DIM n = 0
FOR %val% IN array
tmp[n] = EVAL(callback)
n = n + 1
NEXT
RESIZE(array, RESIZE(tmp))
FOR n = 0 TO RESIZE(tmp)
array[n] = tmp[n]
NEXT
FEND
//////////////////////////////////////////////////
// 【引数】
//   array : 要素を追加する配列(参照引数) 
//   str : 追加する要素 
// 【戻値】
//   処理後の配列の中の要素の数 
//////////////////////////////////////////////////
FUNCTION arrayPush(var arr[], str)
DIM res = RESIZE(arr, UBound(arr) + 1)
arr[res] = str
RESULT = res + 1
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)
SELECT interval
CASE "yyyy"
d = (G_TIME_YY + num) + "/" + G_TIME_MM2 + "/" + G_TIME_DD2
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
CASE "d"
GETTIME(num, date)
d = G_TIME_YY4 + "/" + G_TIME_MM2 + "/" + G_TIME_DD2
CASE "ww"
GETTIME(num * 7, date)
d = G_TIME_YY4 + "/" + G_TIME_MM2 + "/" + G_TIME_DD2
CASE "h"
GETTIME(num / 24, date)
d = G_TIME_YY4 + "/" + G_TIME_MM2 + "/" + G_TIME_DD2 + " " + G_TIME_HH2 + ":" + G_TIME_NN2 + ":" + G_TIME_SS2
CASE "n"
GETTIME(num / 1440, date)
d = G_TIME_YY4 + "/" + G_TIME_MM2 + "/" + G_TIME_DD2 + " " + G_TIME_HH2 + ":" + G_TIME_NN2 + ":" + G_TIME_SS2
CASE "s"
GETTIME(num / 86400, date)
d = G_TIME_YY4 + "/" + G_TIME_MM2 + "/" + G_TIME_DD2 + " " + G_TIME_HH2 + ":" + G_TIME_NN2 + ":" + G_TIME_SS2
SELEND
RESULT = d
FEND
//////////////////////////////////////////////////
// 【引数】
//   interval : 時間単位(yyyy︰年、m︰月、d︰日) 
//   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 "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
SELEND
RESULT = d
FEND
//////////////////////////////////////////////////
// 【引数】
//   deg : 度数法 
// 【戻値】
//   度数法から弧度法に変換した値 
//////////////////////////////////////////////////
FUNCTION degToRad(deg)
DIM pi = 3.14159265358979
RESULT = deg * pi / 180
FEND
//////////////////////////////////////////////////
// 【引数】
//   date : 日付(”YYYYMMDD” or “YYYY/MM/DD” or “YYYY-MM-DD” or “YYYYMMDDHHNNSS” or “YYYY/MM/DD HH:NN:SS”) 
//   m : 第一引数の指定日からプラスマイナス m 月とする(デフォルト=0) 
// 【戻値】
//   date から m 月後の月末の日付 
//////////////////////////////////////////////////
FUNCTION getEndOfMonth(date, m = 0)
GETTIME(0, date)
IFB m >= 0 THEN
year = G_TIME_YY + INT((G_TIME_MM + m + 1) / 12)
month = REPLACE(FORMAT(((G_TIME_MM + m + 1) MOD 12), 2), " ", "0")
ELSE
year = G_TIME_YY + CEIL((G_TIME_MM + m + 1) / 12 - 1)
month = REPLACE(FORMAT(G_TIME_MM - (ABS(m + 1) MOD 12), 2), " ", "0")
IF EVAL(month) < 0 THEN month = REPLACE(FORMAT(12 + EVAL(month), 2), " ", "0")
ENDIF
IF month = "00" THEN month = "12"
day = "01"
d = "" + year + month + day
GETTIME(-1, d)
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
//////////////////////////////////////////////////
// 【引数】
//   数値 : GETTIMEで取得した曜日の番号(G_TIME_WW=0:日曜….6:土曜) 
//   フォーマット : 以下のアルファベットは数値で指定した対応する曜日に置き換えられます。(aaa : 日〜土、aaaa : 日曜日〜土曜日、ddd : Sun〜Sat、dddd : Sunday〜Saturday) 
// 【戻値】
//   数値をフォーマットした文字列を返します。 
//////////////////////////////////////////////////
FUNCTION getWeekdayName(num, format = "aaa")
DIM re = CREATEOLEOBJ("VBScript.RegExp")
DIM aaa[] = "日", "月", "火", "水", "木", "金", "土";
DIM aaaa[] = "日曜日", "月曜日", "火曜日", "水曜日", "木曜日", "金曜日", "土曜日";
DIM ddd[] = "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat";
DIM dddd[] = "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday";
match = reExecute(format, "(a|d)+")
type = match.Item(0).Value
RESULT = reReplace(format, EVAL(type + "[" + num + "]"), type)
FEND
//////////////////////////////////////////////////
// 【引数】
//   シリアル値 : 時間を表すシリアル値を指定 
// 【戻値】
//   例)0…00、0.5…12、1.0…24 
//////////////////////////////////////////////////
FUNCTION Hour(serial)
RESULT = REPLACE(FORMAT(INT(serial * 24), 2), " ", "0")
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
//////////////////////////////////////////////////
// 【引数】
//   日付 : YYYYMMDD 
// 【戻値】
//   TRUE : 日付として認識できる、FALSE : 日付として認識できない 
//////////////////////////////////////////////////
FUNCTION isDate(date)
DIM Pattern = "^(?!([02468][1235679]|[13579][01345789])000229)(([0-9]{4}(01|03|05|07|08|10|12)(0[1-9]|[12][0-9]|3[01]))|([0-9]{4}(04|06|09|11)(0[1-9]|[12][0-9]|30))|([0-9]{4}02(0[1-9]|1[0-9]|2[0-8]))|([0-9]{2}([02468][048]|[13579][26])0229))$"
DIM Match = reExecute(date, Pattern)
RESULT = IIF(Match.Count <> 0, TRUE, FALSE)
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
//////////////////////////////////////////////////
// 【引数】
//   str1 : 置換される文字列 
//   str2 : 置換後の文字列 
//   Pattern : 置換する文字列のパターン 
//   IgnoreCase : 大文字・小文字を区別しない場合はTrue、区別する場合はFalse 
//   Global : 文字列全体を検索する場合はTrue、しない場合はFalse 
// 【戻値】
//   正規表現置換後の文字列 
//////////////////////////////////////////////////
FUNCTION reReplace(str1, str2, Pattern, IgnoreCase = TRUE, Global = TRUE)
DIM re = CREATEOLEOBJ("VBScript.RegExp")
re.Pattern = Pattern
re.IgnoreCase = IgnoreCase
re.Global = Global
RESULT = re.Replace(str1, str2)
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 : フォーマット 
// 【戻値】
//   数値を表示書式に基づいて変換した文字列 
//////////////////////////////////////////////////
FUNCTION text(serial, format)
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"
SELECT TRUE
CASE reTest(format, "\[h+\]")
Matches = reExecute(format, "\[(h+)\]")
RESULT = text(Hour(serial), strRepeat("0", LENGTH(Matches.Item(0).SubMatches(0))))
CASE reTest(format, "^h+$")
Matches = reExecute(format, "^(h+)$")
RESULT = text(Hour(serial) 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"
SELECT text(serial, "m")
CASE 1;  RESULT = "January"
CASE 2;  RESULT = "February"
CASE 3;  RESULT = "March"
CASE 4;  RESULT = "April"
CASE 5;  RESULT = "May"
CASE 6;  RESULT = "June"
CASE 7;  RESULT = "July"
CASE 8;  RESULT = "August"
CASE 9;  RESULT = "September"
CASE 10; RESULT = "October"
CASE 11; RESULT = "November"
CASE 12; RESULT = "December"
SELEND
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 format = "aaaa"
GETTIME(serial, baseDate)
RESULT = getWeekdayName(G_TIME_WW, "aaaa")
CASE format = "aaa"
GETTIME(serial, baseDate)
RESULT = getWeekdayName(G_TIME_WW, "aaa")
CASE format = "dddd"
GETTIME(serial, baseDate)
RESULT = getWeekdayName(G_TIME_WW, "dddd")
CASE format = "ddd"
GETTIME(serial, baseDate)
RESULT = getWeekdayName(G_TIME_WW, "ddd")
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})\](.*?)$")
SELECT Matches.Item(0).SubMatches(0)
CASE 1
CASE 2
CASE 3
RESULT = STRCONV(text(serial, Matches.Item(0).SubMatches(1)), SC_FULLWIDTH)
CASE 4
SELEND
CASE reTest(format, "^(.*?)(AM\/PM|am\/pm|A\/P|a\/p)(.*?)$")
Matches = reExecute(format, "^(.*?)(AM\/PM|am\/pm|A\/P|a\/p)(.*?)$")
res = ""
WITH Matches.Item(0)
res = text(serial, .SubMatches(0)) + .SubMatches(1) + text(serial, .SubMatches(2))
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)) + .SubMatches(3)
ENDWITH
NEXT
RESULT = res
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
//////////////////////////////////////////////////
// 【引数】
//   配列 : 上限値を求める配列 
// 【戻値】
//   配列の上限値 
//////////////////////////////////////////////////
FUNCTION UBound(array[])
RESULT = RESIZE(array)
FEND
//////////////////////////////////////////////////
// 【引数】
//   year : 年 
//   month : 月 
//   day : 日 
//   hour : 時 
//   minute : 分 
//   second : 秒 
// 【戻値】
//   ユリウス日 
//////////////////////////////////////////////////
FUNCTION YMDToJD(year, month, day, hour = 0, minute = 0, second = 0)
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