-- A set of calendar utility functions
CalTools = {};
-- --------------------------------------------------------------
-- CalTools is a set of useful calendar methods
-- --------------------------------------------------------------
-- Returns the 12 hour label corresponding to the hour of the day
--! @param 24 hour of the day (starting at zero)
--! @return a string corresponding to the specified weekday
function CalTools:hourLabel(hourOfDay)
-- todo: add multi-lingual support
hourLabels = {
[0] = "12a", "1a", "2a", "3a", "4a", "5a", "6a", "7a", "8a", "9a", "10a", "11a",
"12p", "1p", "2p", "3p", "4p", "5p", "6p", "7p", "8p", "9p", "10p", "11p",
};
if (nil == hourOfDay) then
error("missing required argument: hourOfDay", 2)
elseif type(hourOfDay) ~= "number" then
error("expected number for hourOfDay, not " .. type(weekday), 2)
elseif ( (hourOfDay < 0) or (hourOfDay>#hourLabels) ) then
error("invalid value for hourOfDay (" .. hourOfDay .. ") must be between 0 and " .. #hourLabels, 2);
end
return hourLabels[hourOfDay];
end
-- Returns the name of the day of the week
--! @param weekday the day of the week (starting at zero)
--! @return a string corresponding to the specified weekday
function CalTools:dayLabel(weekday)
-- todo: add multi-lingual support
dayLabels = { "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" };
if (nil == weekday) then
error("missing required argument: weekday", 2)
elseif type(weekday) ~= "number" then
error("expected number for weekday, not " .. type(weekday), 2)
elseif ( (weekday < 1) or (weekday>#dayLabels) ) then
error("invalid value for weekday (" .. weekday .. ") must be between 1 and " .. #dayLabels, 2);
end
return dayLabels[weekday];
end
MonthLabels = {
"January", "February", "March",
"April", "May", "June",
"July", "August", "September",
"October", "November", "December" };
-- Returns the name of the month
--! @param month of the year (starting at 1)
--! @return a string corresponding to the specified month
function CalTools:monthLabel(month)
if (nil == month) then
error("missing required argument: month", 2)
elseif type(month) ~= "number" then
error("expected number for month, not " .. type(month), 2)
elseif ( (month < 1) or (month>#MonthLabels) ) then
error("invalid value for month (" .. month .. ") must be between 1 and " .. #MonthLabels, 2);
end
return MonthLabels[month];
end
-- Returns the name of the month
--! @param month of the year (starting at 1)
--! @return the index corresponding to monthLabel, or nil on error
function CalTools:monthForLabel(monthLabel)
for idx,label in ipairs(MonthLabels) do
if( monthLabel == label ) then
return idx;
end
end
return nil; -- invalid month name?
end
-- --------------------------------------------------------------
-- isLeapYear (Gregorian calendar)
--
-- Description: determine if year is a leap year
-- Returns: true if the specified year is a leap year, false otherwise
-- Note: Algorithm assumes AD 4 is a leap year in the calendar.
-- --------------------------------------------------------------
function CalTools:isLeapYear(year)
if type(year) ~= "number" then
error("expected number for year, not " .. type(year), 2);
end
local isLeapYear = (math.fmod(year,4)==0 and math.fmod(year,100) ~= 0) or math.fmod(year,400)==0;
return isLeapYear;
end
-- --------------------------------------------------------------
-- daysInMonth (Gregorian calendar)
--
-- Description: Returns the number of days in the specified month & year
-- --------------------------------------------------------------
function CalTools:daysInMonth(month, year)
local daysPerMonth = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
if (nil == month) then
error("missing required argument: month", 2)
elseif type(month) ~= "number" then
error("expected number for month, not " .. type(month), 2)
end
if (nil == year) then
error("missing required argument: year", 2)
elseif type(year) ~= "number" then
error("expected number for year, not " .. type(year), 2)
end
if ( (month == 2) and CalTools:isLeapYear(year)) then
return 29;
end
local days = daysPerMonth[ month ];
return days;
end
-- --------------------------------------------------------------
-- dayOfWeek (Gregorian calendar)
--
-- Description: Returns the weekday (Sunday thru Saturday )
-- for the specified date
-- Returns: 0 for Sunday, 1 for Monday, 2 for Tuesday, etc.
-- Reference: Section 2.6 of version 2.9 of the CALFAQ.
-- --------------------------------------------------------------
function CalTools:dayOfWeek(year, month, day)
--assert(type(year) == "number","year must be a number");
--assert(year >= 1970 ,"year must be >= 1970");
if (nil == year) then
error("missing required argument: year", 2)
elseif type(year) ~= "number" then
error("expected number for year, not " .. type(year), 2)
end
if (nil == month) then
error("missing required argument: month", 2)
elseif type(month) ~= "number" then
error("expected number for month, not " .. type(month), 2)
end
if (nil == day) then
error("missing required argument: day", 2)
elseif type(day) ~= "number" then
error("expected number for day, not " .. type(day), 2)
end
local a = math.floor((14 - month) / 12); -- anchor day
local y = year - a;
local m = month + 12*a - 2;
return math.fmod(math.floor(day + y + math.floor(y/4) - math.floor(y/100) + math.floor(y/400) + (31*m)/12),7);
end
return CalTools;