Module:IriniaCalendar: Difference between revisions
From DSRPG
Created page with "-- Module:IriniaCalendar -- A module for handling the custom calendar of Irinia local p = {} -- Configurable variables for the calendar system local calendar = { -- Current date in the world (can be updated as game progresses) current = { day = 4, month = 5, -- Bloom Moon year = 1236, -- AE (After Establishment) }, -- Month names in order months = { [1] = "Frost Moon", [2] = "Shadow Moon", [3] = "..." |
No edit summary |
||
| (5 intermediate revisions by the same user not shown) | |||
| Line 4: | Line 4: | ||
local p = {} | local p = {} | ||
-- Configurable variables | -- Configurable calendar variables | ||
local calendar = { | local calendar = { | ||
current = { day = 4, month = 5, year = 1236 }, | |||
current = { | |||
months = { | months = { | ||
[1] = "Frost Moon", | [1] = "Frost Moon", [2] = "Shadow Moon", [3] = "Storm Moon", | ||
[4] = "Mist Moon", [5] = "Bloom Moon", [6] = "Sun Moon", | |||
[7] = "Thunder Moon", [8] = "Harvest Moon",[9] = "Ember Moon", | |||
[4] = "Mist Moon", | [10] = "Frost Moon", [11] = "Twilight Moon",[12] = "Star Moon" | ||
[7] = "Thunder Moon", | |||
[10] = "Frost Moon", | |||
}, | }, | ||
days_in_month = { | days_in_month = { | ||
[1] = 30, | [1] = 30, [2] = 28, [3] = 30, [4] = 29, | ||
[5] = 31, [6] = 31, [7] = 30, [8] = 31, | |||
[9] = 30,[10] = 31,[11] = 28,[12] = 30 | |||
[5] = 31, | |||
[9] = 30, | |||
}, | }, | ||
weekdays = { | weekdays = { | ||
[1] = "Silverday", | [1] = "Silverday", [2] = "Brassday", [3] = "Woodday", | ||
[4] = "Stoneday", [5] = "Glassday", [6] = "Steamday", | |||
[4] = "Stoneday", | |||
[7] = "Gearsday" | [7] = "Gearsday" | ||
}, | }, | ||
seasons = { | seasons = { | ||
[1] = "Winter", | [1] = "Winter", [2] = "Winter", [3] = "Spring", | ||
[4] = "Spring", [5] = "Spring", [6] = "Summer", | |||
[7] = "Summer", [8] = "Summer", [9] = "Autumn", | |||
[4] = "Spring", | [10] = "Autumn",[11] = "Autumn",[12] = "Winter" | ||
[7] = "Summer", | |||
[10] = "Autumn", | |||
}, | }, | ||
era = "AE", | era = "AE", | ||
days_in_year = 359 | |||
days_in_year = 359 | |||
} | } | ||
-- | -- Format a date via #invoke args: day, month, year, format | ||
function p. | function p.formatDate(frame) | ||
local args = frame. | local args = frame.args or {} | ||
local day = tonumber(args.day) or calendar.current.day | |||
local month = tonumber(args.month) or calendar.current.month | |||
local year = tonumber(args.year) or calendar.current.year | |||
local fmt = args.format or "full" | |||
local args | |||
if month < 1 or month > #calendar.months then | if month < 1 or month > #calendar.months then | ||
month = ((month - 1) % #calendar.months) + 1 | month = ((month - 1) % #calendar.months) + 1 | ||
end | end | ||
local monthName = calendar.months[month] | local monthName = calendar.months[month] | ||
if fmt == "full" then | |||
if | |||
return day .. " " .. monthName .. ", " .. year .. " " .. calendar.era | return day .. " " .. monthName .. ", " .. year .. " " .. calendar.era | ||
elseif | elseif fmt == "short" then | ||
return day .. " " .. monthName .. ", " .. year | return day .. " " .. monthName .. ", " .. year | ||
elseif | elseif fmt == "month-year" then | ||
return monthName .. ", " .. year .. " " .. calendar.era | return monthName .. ", " .. year .. " " .. calendar.era | ||
elseif | elseif fmt == "day-month" then | ||
return day .. " " .. monthName | return day .. " " .. monthName | ||
elseif | elseif fmt == "numeric" then | ||
return day .. "/" .. month .. "/" .. year .. " " .. calendar.era | return day .. "/" .. month .. "/" .. year .. " " .. calendar.era | ||
else | else | ||
-- fallback for unknown formats | |||
return day .. " " .. monthName .. ", " .. year .. " " .. calendar.era | return day .. " " .. monthName .. ", " .. year .. " " .. calendar.era | ||
end | end | ||
end | end | ||
-- | -- Total days since year 0 | ||
function p.totalDays(date) | function p.totalDays(date) | ||
if not date or not date.day or not date.month or not date.year then | if not date or not date.day or not date.month or not date.year then return 0 end | ||
local total = date.year * calendar.days_in_year | |||
local total = | |||
for i = 1, date.month - 1 do | for i = 1, date.month - 1 do | ||
total = total + calendar.days_in_month[i] | total = total + calendar.days_in_month[i] | ||
end | end | ||
total = total + date.day | total = total + date.day | ||
return total | return total | ||
end | end | ||
-- | -- Compare two dates: returns -1, 0, or 1 | ||
function p. | function p.compareDate(a, b) | ||
if a.year < b.year then return -1 elseif a.year > b.year then return 1 end | |||
if a.month < b.month then return -1 elseif a.month > b.month then return 1 end | |||
if a.day < b.day then return -1 elseif a.day > b.day then return 1 end | |||
return 0 | |||
if | |||
return | |||
end | end | ||
-- Calculate | -- Calculate difference between two dates as a string | ||
function p. | function p.dateDifference(d1, d2) | ||
local | local negative = false | ||
if p.compareDate(d1, d2) > 0 then d1, d2 = d2, d1; negative = true end | |||
if | |||
end | |||
local years = d2.year - d1.year | |||
local months = 0 | |||
local | local days = 0 | ||
local | |||
local | |||
if d2.month >= d1.month then | |||
months = d2.month - d1.month | |||
else | |||
years = years - 1 | |||
months = 12 - d1.month + d2.month | |||
end | end | ||
if d2.day >= d1.day then | |||
days = d2.day - d1.day | |||
else | |||
if months > 0 then | |||
months = months - 1 | |||
if | else | ||
years = years - 1 | |||
months = 11 | |||
end | end | ||
local prev = d2.month - 1 | |||
if prev < 1 then prev = 12 end | |||
days = calendar.days_in_month[prev] - d1.day + d2.day | |||
end | end | ||
local parts = {} | |||
if years ~= 0 then table.insert(parts, years .. " year" .. (years ~= 1 and "s" or "")) end | |||
if months ~= 0 then table.insert(parts, months.. " month" .. (months ~= 1 and "s" or "")) end | |||
if days ~= 0 or #parts == 0 then table.insert(parts, days .. " day" .. (days ~= 1 and "s" or "")) end | |||
if | local result = table.concat(parts, ", ") | ||
if #parts > 1 then | |||
result = string.gsub(result, ", ([^,]*)$", " and %1") | |||
end | end | ||
if negative then result = result .. " ago" end | |||
return result | |||
return | |||
end | end | ||
-- | -- How long since a given date | ||
function p. | function p.timeSince(frame) | ||
local args = frame.args | local args = frame.args or {} | ||
local d = { | |||
day = tonumber(args.day) or 1, | |||
month = tonumber(args.month) or 1, | |||
year = tonumber(args.year) or 0 | |||
} | |||
return p.dateDifference(d, calendar.current) | |||
return calendar. | |||
end | end | ||
-- | -- How long until a given date | ||
function p. | function p.timeUntil(frame) | ||
local args = frame.args | local args = frame.args or {} | ||
local d = { | |||
day = tonumber(args.day) or 1, | |||
month = tonumber(args.month) or 1, | |||
year = tonumber(args.year) or 0 | |||
} | } | ||
return p.dateDifference(calendar.current, d) | |||
end | end | ||
-- Calculate | -- Calculate age in years given birth date | ||
function p. | function p.calculateAge(frame) | ||
local args = frame.args | local args = frame.args or {} | ||
local d = { | |||
day = tonumber(args.day) or 1, | |||
month = tonumber(args.month) or 1, | |||
year = tonumber(args.year) or 0 | |||
} | } | ||
local diff = p.dateDifference(d, calendar.current) | |||
local y = string.match(diff, "^(%d+) years?") | |||
local | return y or "0" | ||
return | |||
end | end | ||
return p | return p | ||
Latest revision as of 20:00, 4 May 2025
Documentation for this module may be created at Module:IriniaCalendar/doc
-- Module:IriniaCalendar
-- A module for handling the custom calendar of Irinia
local p = {}
-- Configurable calendar variables
local calendar = {
current = { day = 4, month = 5, year = 1236 },
months = {
[1] = "Frost Moon", [2] = "Shadow Moon", [3] = "Storm Moon",
[4] = "Mist Moon", [5] = "Bloom Moon", [6] = "Sun Moon",
[7] = "Thunder Moon", [8] = "Harvest Moon",[9] = "Ember Moon",
[10] = "Frost Moon", [11] = "Twilight Moon",[12] = "Star Moon"
},
days_in_month = {
[1] = 30, [2] = 28, [3] = 30, [4] = 29,
[5] = 31, [6] = 31, [7] = 30, [8] = 31,
[9] = 30,[10] = 31,[11] = 28,[12] = 30
},
weekdays = {
[1] = "Silverday", [2] = "Brassday", [3] = "Woodday",
[4] = "Stoneday", [5] = "Glassday", [6] = "Steamday",
[7] = "Gearsday"
},
seasons = {
[1] = "Winter", [2] = "Winter", [3] = "Spring",
[4] = "Spring", [5] = "Spring", [6] = "Summer",
[7] = "Summer", [8] = "Summer", [9] = "Autumn",
[10] = "Autumn",[11] = "Autumn",[12] = "Winter"
},
era = "AE",
days_in_year = 359
}
-- Format a date via #invoke args: day, month, year, format
function p.formatDate(frame)
local args = frame.args or {}
local day = tonumber(args.day) or calendar.current.day
local month = tonumber(args.month) or calendar.current.month
local year = tonumber(args.year) or calendar.current.year
local fmt = args.format or "full"
if month < 1 or month > #calendar.months then
month = ((month - 1) % #calendar.months) + 1
end
local monthName = calendar.months[month]
if fmt == "full" then
return day .. " " .. monthName .. ", " .. year .. " " .. calendar.era
elseif fmt == "short" then
return day .. " " .. monthName .. ", " .. year
elseif fmt == "month-year" then
return monthName .. ", " .. year .. " " .. calendar.era
elseif fmt == "day-month" then
return day .. " " .. monthName
elseif fmt == "numeric" then
return day .. "/" .. month .. "/" .. year .. " " .. calendar.era
else
-- fallback for unknown formats
return day .. " " .. monthName .. ", " .. year .. " " .. calendar.era
end
end
-- Total days since year 0
function p.totalDays(date)
if not date or not date.day or not date.month or not date.year then return 0 end
local total = date.year * calendar.days_in_year
for i = 1, date.month - 1 do
total = total + calendar.days_in_month[i]
end
total = total + date.day
return total
end
-- Compare two dates: returns -1, 0, or 1
function p.compareDate(a, b)
if a.year < b.year then return -1 elseif a.year > b.year then return 1 end
if a.month < b.month then return -1 elseif a.month > b.month then return 1 end
if a.day < b.day then return -1 elseif a.day > b.day then return 1 end
return 0
end
-- Calculate difference between two dates as a string
function p.dateDifference(d1, d2)
local negative = false
if p.compareDate(d1, d2) > 0 then d1, d2 = d2, d1; negative = true end
local years = d2.year - d1.year
local months = 0
local days = 0
if d2.month >= d1.month then
months = d2.month - d1.month
else
years = years - 1
months = 12 - d1.month + d2.month
end
if d2.day >= d1.day then
days = d2.day - d1.day
else
if months > 0 then
months = months - 1
else
years = years - 1
months = 11
end
local prev = d2.month - 1
if prev < 1 then prev = 12 end
days = calendar.days_in_month[prev] - d1.day + d2.day
end
local parts = {}
if years ~= 0 then table.insert(parts, years .. " year" .. (years ~= 1 and "s" or "")) end
if months ~= 0 then table.insert(parts, months.. " month" .. (months ~= 1 and "s" or "")) end
if days ~= 0 or #parts == 0 then table.insert(parts, days .. " day" .. (days ~= 1 and "s" or "")) end
local result = table.concat(parts, ", ")
if #parts > 1 then
result = string.gsub(result, ", ([^,]*)$", " and %1")
end
if negative then result = result .. " ago" end
return result
end
-- How long since a given date
function p.timeSince(frame)
local args = frame.args or {}
local d = {
day = tonumber(args.day) or 1,
month = tonumber(args.month) or 1,
year = tonumber(args.year) or 0
}
return p.dateDifference(d, calendar.current)
end
-- How long until a given date
function p.timeUntil(frame)
local args = frame.args or {}
local d = {
day = tonumber(args.day) or 1,
month = tonumber(args.month) or 1,
year = tonumber(args.year) or 0
}
return p.dateDifference(calendar.current, d)
end
-- Calculate age in years given birth date
function p.calculateAge(frame)
local args = frame.args or {}
local d = {
day = tonumber(args.day) or 1,
month = tonumber(args.month) or 1,
year = tonumber(args.year) or 0
}
local diff = p.dateDifference(d, calendar.current)
local y = string.match(diff, "^(%d+) years?")
return y or "0"
end
return p