Mô đun:Âm lịch

local p = {};
local function toint(n)
local s = tostring(n)
local i, j = s:find('%.')
if i then
return tonumber(s:sub(1, i-1))
else
return n
end
end
local function UniversalToJD(D, M, Y)
	local JD
	if (Y > 1582 or (Y == 1582 and M > 10) or (Y == 1582 and M == 10 and D > 14)) then
		JD = 367*Y - toint(7*(Y+toint((M+9)/12))/4) - toint(3*(toint((Y+(M-9)/7)/100)+1)/4) + toint(275*M/9)+D+1721028.5
	else
		JD = 367*Y - toint(7*(Y+5001+toint((M-9)/7))/4) + toint(275*M/9)+D+1729776.5
	end
	return JD
end
function UniversalFromJD(JD)
--	local JD = tonumber(frame.args.JD)
	local Z, A, alpha, B, C, D, E, dd, mm, yyyy, F
	Z = toint(JD+0.5)
	F = (JD+0.5)-Z
if (Z  3*math.pi/2 then
		jd = NewMoon(k-1)
	end
	return LocalFromJD(jd, utc)
end
local function LunarYear(Y, b, utc)
	local ret1 = {}
	local ret2 = {}
	local ret3 = {}
	local ret4 = {}
	local ret5 = {}
	local month11A = {LunarMonth11(Y-1, utc)}
	local jdMonth11A = LocalToJD(month11A1, month11A2, month11A3, utc)
	local k = math.floor(0.5 + (jdMonth11A - 2415021.076998695) / 29.530588853)
	local month11B = {LunarMonth11(Y, utc)}
	local off = LocalToJD(month11B1, month11B2, month11B3, utc) - jdMonth11A
	local leap
	local retlength
	local i
	if off > 365.0 then
		retlength = 14
		leap = true
	else
		retlength = 13
		leap = false
	end
	ret11 = month11A1
	ret21 = month11A2
	ret31 = month11A3
	ret41 = 0
	ret51 = 0
	ret1retlength = month11B1
	ret2retlength = month11B2
	ret3retlength = month11B3
	ret4retlength = 0
	ret5retlength = 0
	for i = 2, (retlength - 1) do
		local nm = NewMoon(k+i-1)
		local a = {LocalFromJD(nm, utc)}
		ret1i = a1
		ret2i = a2
		ret3i = a3
		ret4i = 0
		ret5i = 0
	end
	for i = 1, retlength do
		ret4i = math.mod(i + 10, 12)
	end
	if leap == true then
		local sunLongitudes = {}
	sunLongitudesretlength+1 = 0
	for i = 1, retlength do
		local a = {ret1i, ret2i, ret3i, ret4i, ret5i}
		local jdAtMonthBegin = LocalToJD(a1, a2, a3, utc)
		sunLongitudesi = SunLongitude(jdAtMonthBegin)
	end
	local found = false
	for i = 1, retlength do
		if found == true then
			ret4i = math.mod(i+9, 12)
		end
		local sl1 = sunLongitudesi
		local sl2 = sunLongitudesi+1
		local hasMajorTerm
	    	if math.floor(sl1/math.pi*6) == math.floor(sl2/math.pi*6) then
	     		found = true
	     		ret5i = 1
	     		ret4i = math.mod(i+9, 12)
	    	end
	end
	end
	if b == 1 then
		return unpack(ret1)
	else
		if b == 2 then
		    return unpack(ret2)
		else
			if b == 3 then
	        	return unpack(ret3)
		    else
		    	if b == 4 then
	            	return unpack(ret4)
	         	else
	         		if b == 5 then
		                return unpack(ret5)
		            else
		                return retlength
		            end
		    	end
			end
		end
end
end
local function Solar2Lunar(D, M, Y, utc)
	local yy = Y
	local ly1 = {LunarYear(Y,1, utc)}
	local ly2 = {LunarYear(Y,2, utc)}
	local ly3 = {LunarYear(Y,3, utc)}
	local ly4 = {LunarYear(Y,4, utc)}
	local ly5 = {LunarYear(Y,5, utc)}
	local month11length = LunarYear(Y,6, utc)
	local month11 = {ly1month11length, ly2month11length, ly3month11length}
	local jdToday = LocalToJD(D, M, Y, utc)
	local jdMonth11 = LocalToJD(month111, month112, month113, utc)
	if (jdToday > jdMonth11 or jdToday == jdMonth11) then
		ly1 = {LunarYear(Y+1,1, utc)}
	    ly2 = {LunarYear(Y+1,2, utc)}
ly3 = {LunarYear(Y+1,3, utc)}
	    ly4 = {LunarYear(Y+1,4, utc)}
	    ly5 = {LunarYear(Y+1,5, utc)}
	    yy = Y + 1
	end
	local i = LunarYear(Y,6, utc)
	while jdToday  1 do
		i = i -1
	end
	local dd = toint(jdToday - LocalToJD(ly1i, ly2i, ly3i, utc)) + 1
	local mm = ly4i
	if mm >= 11 or mm == 0 then
		yy = yy -1
	end
	return unpack{dd, mm, yy, ly5i}
end
function p.Lunar2Solar(frame)
	D = tonumber(frame.args.D)
	M = tonumber(frame.args.M)
	Y = tonumber(frame.args.Y)
	utc = tonumber(frame.args.utc)
	DF = frame.args.DF
	local leap = tonumber(frame.args.nhuan)
local yy = Y
if M>= 11 then
	yy = Y + 1
end
local lm = {}
local lm1 = {LunarYear(yy, 1, utc)}
local lm2 = {LunarYear(yy, 2, utc)}
local lm3 = {LunarYear(yy, 3, utc)}
local lm4 = {LunarYear(yy, 4, utc)}
local lm5 = {LunarYear(yy, 5, utc)}
local length = LunarYear(yy, 6, utc)
local lunarMonth = {}
local jd
lunarMonth1 = {"null"}
local i
if M == 12 then
	M = 0
end
for i = 1, length do
	lm = {lm1i, lm2i, lm3i, lm4i, lm5i}
if lm4 == M and lm5 == leap then
lunarMonth = {lm1, lm2, lm3}
break
end
end
	if unpack{lunarMonth} == "null" then
		return "Lỗi nhập!"
	else
		jd = LocalToJD(lunarMonth1, lunarMonth2, lunarMonth3, utc)
		local dmy = {LocalFromJD(jd + D - 1, utc)}
		if DF == 'full' then
	    return string.format ('ngày %d tháng %d năm %d', dmy1, dmy2, dmy3)
		else
		if DF == 'jMY' then
	    return string.format ('%d tháng %d năm %d', dmy1, dmy2, dmy3)
		else
		if DF == 'dFY' then
	    return string.format ('%02d tháng %02d năm %d', dmy1, dmy2, dmy3)
		else
	if DF == 'dm' then
	    return string.format ('%02d%02d', dmy1, dmy2)
	else
	if DF == 'd-m-y' then
	    return string.format ('%02d-%02d-%02d', dmy1, dmy2, dmy3)
	else
	if DF == 'jM' then
		return string.format ('%d tháng %d', dmy1, dmy2)
	    else
	if DF == 'dM' then
		return string.format ('%02d tháng %d', dmy1, dmy2)
	else
	if DF == 'Y' then
		return string.format ('%02d', dmy3)
	else
	if DF == 'j' then
		return string.format ('%d', dmy1)
	else
	if DF == 'd' then
		return string.format ('%02d', dmy1)
	else
	if DF == 'n' then
		return string.format ('%d', dmy2)
	else
	if DF == 'm' then
		return string.format ('%02d', dmy2)
	else
	if DF == 'M' then
		return string.format ('tháng %d', dmy2)
	else
	if DF == 'F' then
		return string.format ('tháng %02d', dmy2)
	end end end end end end end end end end end end end end
	end
end
local function canchi (x)
	local a = x%10
	local b = x%12
	local can, chi
	if a == 1 then
		can = "Giáp"
else
	if a == 2 then
	can = "Ất"
else
	if a == 3 then
	can = "Bính"
else
	if a == 4 then
	can = "Đinh"
else
	if a == 5 then
	can = "Mậu"
else
	if a == 6 then
	can = "Kỷ"
else
	if a == 7 then
		can = "Canh"
	else
	if a == 8 then
	can = "Tân"
else
	if a == 9 then
	    can = "Nhâm"
else
if a == 0 then
		can = "Quý"
end end end end end end end end end end
	if b == 1 then
		chi = "Tý"
else
	if b == 2 then
	chi = "Sửu"
else
	if b == 3 then
	chi = "Dần"
else
	if b == 4 then
	chi = "Mão"
else
	if b == 5 then
	chi = "Thìn"
else
	if b == 6 then
	chi = "Tỵ" 
else
	if b == 7 then
	chi = "Ngọ"
else
	if b == 8 then
	chi = "Mùi"
else
	if b == 9 then
		chi = "Thân"
	else
	if b == 10 then
	chi = "Dậu"
else
	if b == 11 then
	    chi = "Tuất"
else
if b == 0 then
		chi = "Hợi"
end end end end end end end end end end end end
	return string.format ('%s %s', can, chi)
end
function p.main(frame)
	D = tonumber(frame.args.D)
	M = tonumber(frame.args.M)
	Y = tonumber(frame.args.Y)
	DF = frame.args.DF
	utc = tonumber(frame.args.utc)
	local ngay, thang, nam, nhuan
	local LunarDM = {Solar2Lunar(D, M, Y, utc)}
	ngay = LunarDM1
	if LunarDM2 == 0 then
		thang = 12
	else
		thang = LunarDM2
	end
	nam = LunarDM3
	local canchinam = canchi (nam+57)
	local canchithang = canchi (nam*12+thang+14)
	local canchingay = canchi (toint(LocalToJD(D, M, Y, utc)+51.5))
	if LunarDM4 == 1 then
		nhuan = " (nhuận)"
	else
		nhuan = ""
	end
if DF == 'full' and ngay  10 then
return string.format ('ngày %d tháng %d%s năm %s', ngay, thang, nhuan, canchinam)
else
if DF == 'dm' then
return string.format ('%02d%02d', ngay, thang)
else
if DF == 'jM' then
	return string.format ('%d tháng %02d%s', ngay, thang, nhuan)
else
if DF == 'dM' then
	return string.format ('%02d tháng %d%s', ngay, thang, nhuan)
else
if DF == 'Y' then
	return string.format ('%s', canchi)
else
if DF == 'j' then
	return string.format ('%d', ngay)
else
if DF == 'd' then
	return string.format ('%02d', ngay)
else
if DF == 'n' then
	return string.format ('%d', thang)
else
if DF == 'm' then
	return string.format ('%02d', thang)
else
if DF == 'M' then
	return string.format ('tháng %d', thang)
else
if DF == 'F' then
	return string.format ('tháng %02d', thang)
else
if DF == 'YY' then
	return string.format ('%s', canchinam)
else
if DF == 'MM' then
	return string.format ('%s', canchithang)
else
if DF == 'DD' then
	return string.format ('%s', canchingay)
else
if DF == 'DDMMYY' then
	return string.format ('ngày %s tháng %s năm %s', canchingay, canchithang, canchinam)
end end end end end end end end end end end end end end end end
end
return p