Module:Calendar/rokaselan

From Nguhcraft Wiki
Jump to navigation Jump to search

Documentation for this module may be created at Module:Calendar/rokaselan/doc

local calendar = {}

local epoch_offset = -870294
local month_names = { "Sairairita", "Nilarita", "Rekarita", "Towanrita", "Eskelrita", "Kastarita", "Rokorita", "Korakarita", "Merikrita", "Rikulrita", "Parfarita" }
local day_names = { [0] = "Akkage", "Dungkage", "Rencage", "Kenénage", "Minákkage", "Rikudage", "Pinakage", "Akkage" }

local function era_of(year_mk)
	if year_mk <= 1219 then return year_mk, "Misha Kótan" end
	if year_mk <= 1636 then return year_mk - 1219, "Remuymaga" end
	if year_mk <= 1708 then return year_mk - 1636, "Kagyuha" end
	if year_mk <= 2024 then return year_mk - 1708, "Karlan" end
	if year_mk <= 2198 then return year_mk - 2024, "Dúrisa" end
	if year_mk <= 2338 then return year_mk - 2198, "Peska" end
	--[[if year_mk <= current era then ]] return year_mk - 2338, "Kanata"
end

local function is_leap(year)
	local cycle_point = year % 33
	return cycle_point % 4 == 0 and cycle_point ~= 32
end

local function month_len(m, y)
	if m >= 1 and m <= 6 then return 31 end
	if m >= 7 and m <= 11 then return 30 end
	if m == 12 then return is_leap(y) and 30 or 29 end
end

calendar.from = function(date_info)
	assert(date_info.year and date_info.month and date_info.day)
	date_info.year = tonumber(date_info.year)
	date_info.month = tonumber(date_info.month)
	date_info.day = tonumber(date_info.day)
	
	local cycles = date_info.year / 33
	local cycle_pos = date_info.year % 33
	local days = math.floor(cycles) * 12053
	for year = 0, cycle_pos - 1 do
		days = days + (is_leap(year) and 366 or 365)
	end
	for month = 1, date_info.month do
		days = days + month_len(month, date_info.year)
	end
	days = days + date_info.days
	return days + epoch_offset
end

calendar.to = function(datestamp)
	datestamp = tonumber(datestamp)
	local days = datestamp - epoch_offset
	local cycles = days / 12053
	local year = math.floor(cycles) * 33
	local days = days - math.floor(cycles) * 12053
	
	while days >= 366 do
		days = days - (is_leap(year) and 366 or 365)
		year = year + 1
	end
	if days == 365 and not is_leap(year) then
		days = days - 365
		year = year + 1
	end
	local month, day
	if days > 186 then
		days = days - 186
		month = math.floor(days/30) + 7
		day = days % 30 + 1
	else
		month = math.floor(days / 31) + 1
		day = days % 31 + 1
	end
	return {year = year, month = month, day = day, weekday = (datestamp - epoch_offset) % 7}
end

calendar.to_formatted = function(datestamp, opts)
	opts.erastyle = opts.erastyle or "both"
	local date = calendar.to(datestamp)
	local era_year, era = era_of(date.year) 
	local formatted_year
	if opts.erastyle == "mk" then
		formatted_year = " " .. tostring(date.year) .. " MK"
	elseif opts.erastyle == "era" then
		formatted_year = ", " .. era .. " " .. tostring(era_year)
	elseif opts.erastyle == "both" then
		formatted_year = ", " .. era .. " " .. tostring(era_year) .. " (" .. tostring(date.year) .. " MK)"
	else
		error("unsupported era style: " .. opts.erastyle)
	end
	return string.format("%s %d %s%s", day_names[date.weekday], date.day, month_names[date.month], formatted_year)
end

return calendar