Module:Date: Difference between revisions
clean up and some aliases
(major refactor, mostly working now; add/subtract with a date; remove template handling which will be in Module:Age) |
(clean up and some aliases) |
||
Line 1: | Line 1: | ||
-- Date functions | -- Date functions for use by other modules. | ||
-- I18N and time zones are not supported. | -- I18N and time zones are not supported. | ||
local MINUS = '−' -- Unicode U+2212 MINUS SIGN | local MINUS = '−' -- Unicode U+2212 MINUS SIGN | ||
local Date, DateDiff, datemt -- forward declarations | |||
local function is_date(t) | |||
return type(t) == 'table' and getmetatable(t) == datemt | |||
end | |||
local function collection() | local function collection() | ||
Line 46: | Line 52: | ||
local function days_in_month(year, month, calname) | local function days_in_month(year, month, calname) | ||
-- Return number of days (1..31) in given month (1..12). | -- Return number of days (1..31) in given month (1..12). | ||
if month == 2 and is_leap_year(year, calname) then | if month == 2 and is_leap_year(year, calname) then | ||
return 29 | return 29 | ||
end | end | ||
return | return ({ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 })[month] | ||
end | end | ||
Line 341: | Line 346: | ||
local function _date_text(date, fmt, options) | local function _date_text(date, fmt, options) | ||
-- Return formatted string from given date. | -- Return formatted string from given date. | ||
if not is_date(date) then | |||
return 'Need a date (use "date:text()" with a colon).' | |||
end | |||
if type(fmt) ~= 'string' then | if type(fmt) ~= 'string' then | ||
fmt = '%-d %B %-Y %{era}' | fmt = '%-d %B %-Y %{era}' | ||
Line 423: | Line 431: | ||
end | end | ||
-- A table to get the current | -- A table to get the current date/time (UTC), but only if needed. | ||
local current = setmetatable({}, { | local current = setmetatable({}, { | ||
__index = function (self, key) | __index = function (self, key) | ||
Line 574: | Line 582: | ||
end | end | ||
return date, options | return date, options | ||
end | end | ||
Line 688: | Line 690: | ||
elseif key == 'dow' then | elseif key == 'dow' then | ||
value = (self.jd + 1) % 7 -- day-of-week 0=Sun to 6=Sat | value = (self.jd + 1) % 7 -- day-of-week 0=Sun to 6=Sat | ||
elseif key == 'dayofweek' then | |||
value = self.dow | |||
elseif key == 'dowiso' then | elseif key == 'dowiso' then | ||
value = (self.jd % 7) + 1 -- ISO day-of-week 1=Mon to 7=Sun | value = (self.jd % 7) + 1 -- ISO day-of-week 1=Mon to 7=Sun | ||
elseif key == 'dayofweekiso' then | |||
value = self.dowiso | |||
elseif key == 'doy' then | elseif key == 'doy' then | ||
local first = Date(self.year, 1, 1, self.calname).jd | local first = Date(self.year, 1, 1, self.calname).jd | ||
value = self.jd - first + 1 -- day-of-year 1 to 366 | value = self.jd - first + 1 -- day-of-year 1 to 366 | ||
elseif key == 'dayofyear' then | |||
value = self.doy | |||
elseif key == 'era' then | elseif key == 'era' then | ||
-- Era text ( | -- Era text (never a negative sign) from year and options. | ||
value = get_era_for_year(self.options.era, self.year) | value = get_era_for_year(self.options.era, self.year) | ||
elseif key == 'gsd' then | elseif key == 'gsd' then | ||
Line 700: | Line 708: | ||
-- which is JDN = 1721426, and is from jd 1721425.5 to 1721426.49999. | -- which is JDN = 1721426, and is from jd 1721425.5 to 1721426.49999. | ||
value = math.floor(self.jd - 1721424.5) | value = math.floor(self.jd - 1721424.5) | ||
elseif key == 'jd' or key == 'jdz' then | elseif key == 'juliandate' or key == 'jd' or key == 'jdz' then | ||
local jd, jdz = julian_date(self) | local jd, jdz = julian_date(self) | ||
rawset(self, 'juliandate', jd) | |||
rawset(self, 'jd', jd) | rawset(self, 'jd', jd) | ||
rawset(self, 'jdz', jdz) | rawset(self, 'jdz', jdz) | ||
return key == ' | return key == 'jdz' and jdz or jd | ||
elseif key == ' | elseif key == 'isleapyear' then | ||
value = is_leap_year(self.year, self.calname) | value = is_leap_year(self.year, self.calname) | ||
elseif key == 'monthabbr' then | elseif key == 'monthabbr' then | ||
value = month_info[self.month][1] | value = month_info[self.month][1] | ||
elseif key == 'monthdays' then | |||
value = days_in_month(self.year, self.month, self.calname) | |||
elseif key == 'monthname' then | elseif key == 'monthname' then | ||
value = month_info[self.month][2] | value = month_info[self.month][2] | ||
Line 718: | Line 729: | ||
end, | end, | ||
} | } | ||
--[[ Examples of syntax to construct a date: | --[[ Examples of syntax to construct a date: | ||
Line 748: | Line 755: | ||
minute = 0, | minute = 0, | ||
second = 0, | second = 0, | ||
options = make_option_table(), | options = make_option_table(), | ||
text = _date_text, | text = _date_text, | ||
Line 847: | Line 853: | ||
-- The difference is negative if date2 is more recent than date1. | -- The difference is negative if date2 is more recent than date1. | ||
-- Return nothing if invalid. | -- Return nothing if invalid. | ||
if not (date1 and date2 and date1.calname == date2.calname) then | if not (is_date(date1) and is_date(date2) and date1.calname == date2.calname) then | ||
return | return | ||
end | end | ||
Line 898: | Line 904: | ||
_current = current, | _current = current, | ||
_Date = Date, | _Date = Date, | ||
_days_in_month = days_in_month, | _days_in_month = days_in_month, | ||
} | } |