Module:Date: Difference between revisions
date:list() now accepts a count; DateDiff methods age and duration; cleaner member names; remember if time entered with an am/pm option for default output
(rework date differences for more consistent years/months/days; differences include hours/minutes/seconds; can add 'date + diff'; tweaks) |
(date:list() now accepts a count; DateDiff methods age and duration; cleaner member names; remember if time entered with an am/pm option for default output) |
||
| Line 85: | Line 85: | ||
local a = floor((14 - date.month)/12) | local a = floor((14 - date.month)/12) | ||
local y = date.year + 4800 - a | local y = date.year + 4800 - a | ||
if date. | if date.calendar == 'Julian' then | ||
offset = floor(y/4) - 32083 | offset = floor(y/4) - 32083 | ||
else | else | ||
| Line 105: | Line 105: | ||
-- This handles the proleptic Julian and Gregorian calendars. | -- This handles the proleptic Julian and Gregorian calendars. | ||
-- Negative Julian dates are not defined but they work. | -- Negative Julian dates are not defined but they work. | ||
local calname = date. | local calname = date.calendar | ||
local low, high -- min/max limits for date ranges −9999-01-01 to 9999-12-31 | local low, high -- min/max limits for date ranges −9999-01-01 to 9999-12-31 | ||
if calname == 'Gregorian' then | if calname == 'Gregorian' then | ||
| Line 166: | Line 166: | ||
(-9999 <= y and y <= 9999 and | (-9999 <= y and y <= 9999 and | ||
1 <= m and m <= 12 and | 1 <= m and m <= 12 and | ||
1 <= d and d <= days_in_month(y, m, date. | 1 <= d and d <= days_in_month(y, m, date.calendar)) then | ||
return | return | ||
end | end | ||
| Line 199: | Line 199: | ||
-- If options1 is a string, return a table with its settings, or | -- If options1 is a string, return a table with its settings, or | ||
-- if it is a table, use its settings. | -- if it is a table, use its settings. | ||
-- Missing options are set from options2 or defaults. | -- Missing options are set from table options2 or defaults. | ||
-- If a default is used, a flag is set so caller knows the value was not intentionally set. | |||
-- Valid option settings are: | -- Valid option settings are: | ||
-- am: 'am', 'a.m.', 'AM', 'A.M.' | -- am: 'am', 'a.m.', 'AM', 'A.M.' | ||
| Line 209: | Line 210: | ||
-- BCMINUS displays a MINUS if year < 0 and the display format does not include %{era}. | -- BCMINUS displays a MINUS if year < 0 and the display format does not include %{era}. | ||
-- BCNEGATIVE is similar but displays a hyphen. | -- BCNEGATIVE is similar but displays a hyphen. | ||
local result = {} | local result = { bydefault = {} } | ||
if type(options1) == 'table' then | if type(options1) == 'table' then | ||
result = options1 | result.am = options1.am | ||
result.era = options1.era | |||
elseif type(options1) == 'string' then | elseif type(options1) == 'string' then | ||
-- Example: 'am:AM era:BC' or 'am=AM era=BC'. | -- Example: 'am:AM era:BC' or 'am=AM era=BC'. | ||
| Line 224: | Line 226: | ||
local defaults = { am = 'am', era = 'BC' } | local defaults = { am = 'am', era = 'BC' } | ||
for k, v in pairs(defaults) do | for k, v in pairs(defaults) do | ||
result[k] | if not result[k] then | ||
if options2[k] then | |||
result[k] = options2[k] | |||
else | |||
result[k] = v | |||
result.bydefault[k] = true | |||
end | |||
end | |||
end | end | ||
return result | return result | ||
| Line 287: | Line 296: | ||
M = { fmt = '%02d', fmt2 = '%d', field = 'minute' }, | M = { fmt = '%02d', fmt2 = '%d', field = 'minute' }, | ||
S = { fmt = '%02d', fmt2 = '%d', field = 'second' }, | S = { fmt = '%02d', fmt2 = '%d', field = 'second' }, | ||
j = { fmt = '%03d', fmt2 = '%d', field = ' | j = { fmt = '%03d', fmt2 = '%d', field = 'dayofyear' }, | ||
I = { fmt = '%02d', fmt2 = '%d', field = 'hour', special = 'hour12' }, | I = { fmt = '%02d', fmt2 = '%d', field = 'hour', special = 'hour12' }, | ||
p = { field = 'hour', special = 'am' }, | p = { field = 'hour', special = 'am' }, | ||
| Line 372: | Line 381: | ||
end | end | ||
if type(fmt) ~= 'string' then | if type(fmt) ~= 'string' then | ||
fmt = ' | fmt = 'dmy' | ||
if date.hastime then | if date.hastime then | ||
fmt = (date.second > 0 and 'hms ' or 'hm ') .. fmt | |||
end | end | ||
elseif fmt:find('%', 1, true) then | |||
return strftime(date, fmt, options) | return strftime(date, fmt, options) | ||
end | end | ||
local function hm_fmt() | |||
local plain = make_option_table(options, date.options).bydefault.am | |||
return plain and '%H:%M' or '%-I:%M %p' | |||
end | end | ||
local need_time = date.hastime | |||
local t = collection() | local t = collection() | ||
for item in fmt:gmatch('%S+') do | for item in fmt:gmatch('%S+') do | ||
local f | local f | ||
if item == 'hm' then | < | ||