モジュール:ヨーグレキ
2つの関数を使用できます。
関数名 | 引数1 | 引数2 | 引数3 | 引数4 | 出力 | 使用例 |
---|---|---|---|---|---|---|
gregorianToYogurian | グレゴリオ暦における年 | グレゴリオ暦における月 | グレゴリオ暦における日 | 出力のフォーマット | ヨーグレキのテーブル | *{{#invoke:ヨーグレキ|gregorianToYogurian|2021|12|25|%d-%d-%d}} : Lua エラー 16 行目: attempt to compare number with nil[1]
|
yogurianToGregorian | ヨーグレキにおける年 | ヨーグレキにおける月 | ヨーグレキにおける日 | 出力のフォーマット | グレゴリオ暦のテーブル | *{{#invoke:ヨーグレキ|yogurianToGregorian|11|1|1|%d-%d-%d}} : Lua エラー 21 行目: attempt to compare number with nil[2]
|
local p = {}
MONTH_DAYS = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
local function isLeap(year)
return year % 4 == 0 and (year % 100 ~= 0 or year % 400 == 0)
end
local function leapdays(y1, y2)
y1 = y1 - 1
y2 = y2 - 1
return (math.floor(y2 / 4) - math.floor(y1 / 4)) - (math.floor(y2 / 100) - math.floor(y1 / 100)) +
(math.floor(y2 / 400) - math.floor(y1 / 400))
end
local function isValidDate(gYear, gMonth, gDay)
return gMonth > 0 and gMonth <= 12 and gDay > 0 and gDay <=
(MONTH_DAYS[gMonth] + ((gMonth == 2 and isLeap(gYear)) and 1 or 0))
end
local function isYogurianValidDate(yYear, yMonth, yDay)
return yMonth > 0 and yMonth <= 12 and yDay > 0 and yDay <= 30 +
(yMonth == 1 and (isLeap(yYear + 2020) and 6 or 5) or 0)
end
local function checkValidDate(gYear, gMonth, gDay)
if not isValidDate(gYear, gMonth, gDay) then
error(string.format("Date %d-%d-%d is invalid.", gYear, gMonth, gDay))
end
end
local function checkYogurianValidDate(yYear, yMonth, yDay)
if not isYogurianValidDate(yYear, yMonth, yDay) then
error(string.format("Yogurian date %d-%d-%d is invalid.", yYear, yMonth, yDay))
end
end
local function ddCalculate(y1, m1, d1, y2, m2, d2)
yd = y2 - y1
dd = yd * 365 + leapdays(y1, y2 + 1)
if isLeap(y1) then
if m1 > 2 then
dd = dd - 1
end
end
if isLeap(y2) and y1 < y2 then
if m2 < 3 then
dd = dd - 1
end
end
for mi = 1, m2 - 1 do
dd = dd + MONTH_DAYS[mi]
end
for mi = 1, m1 - 1 do
dd = dd - MONTH_DAYS[mi]
end
dd = dd + d2 - d1
return dd
end
local function gregorianToYogurian(gYear, gMonth, gDay)
checkValidDate(gYear, gMonth, gDay)
isLeapB = isLeap(gYear + (gMonth >= 11 and 1 or 0))
d = ddCalculate(2020, 11, 1, gYear, gMonth, gDay)
yy = gYear - 2019 - (gMonth >= 11 and 0 or 1)
dfn = d - 365 * (yy - 1) - leapdays(2021, gYear + (gMonth >= 11 and 1 or 0)) + 1
hmd = isLeapB and 36 or 35
ym = dfn <= hmd and 1 or math.floor((dfn - hmd - 1) / 30) + 2
yd = ym == 1 and dfn or (dfn - hmd - 1) % 30 + 1
return {yy, ym, yd}
end
local function yogurianToGregorian(yYear, yMonth, yDay)
checkYogurianValidDate(yYear, yMonth, yDay)
isLeapB = isLeap(yYear + 2020)
gDay = yMonth == 1 and yDay or (yMonth - 2) * 30 + (isLeapB and 36 or 35) + yDay
gYear = yYear + 2019 + (gDay > 61 and 1 or 0)
gMonth = 11
while true do
gMonth = gMonth - (gMonth > 12 and 12 or 0)
monthDay = MONTH_DAYS[gMonth] + ((isLeapB and gMonth == 2) and 1 or 0)
if gDay <= monthDay then
break
end
gDay = gDay - monthDay
gMonth = gMonth + 1
end
return {gYear, gMonth, gDay}
end
p.gregorianToYogurian = gregorianToYogurian
p.yogurianToGregorian = yogurianToGregorian
return p