Module:Date: Difference between revisions

210 bytes added ,  8 years ago
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 for implementing templates and for use by other modules.
-- 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).
local month_days = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }
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 month_days[month]
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 year/month/day (UTC), but only if needed.
-- 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
local Date, DateDiff, datemt  -- forward declarations
local function is_date(t)
return type(t) == 'table' and getmetatable(t) == datemt
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 (not a negative sign) from year and options.
-- 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 == 'jd' and jd or jdz
return key == 'jdz' and jdz or jd
elseif key == 'is_leap_year' then
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,
}
}
local function _month_days(date, month)
return days_in_month(date.year, month, date.calname)
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,
month_days = _month_days,
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,
_DateDiff = DateDiff,
_days_in_month = days_in_month,
_days_in_month = days_in_month,
}
}
Anonymous user