Module:Date: Difference between revisions

2,645 bytes added ,  9 years ago
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.calname == 'Julian' then
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.calname
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.calname)) then
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] = result[k] or options2[k] or v
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 = 'doy' },
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 = '%-d %B %-Y %{era}'
fmt = 'dmy'
if date.hastime then
if date.hastime then
if date.second > 0 then
fmt = (date.second > 0 and 'hms ' or 'hm ') .. fmt
fmt = '%H:%M:%S ' .. fmt
else
fmt = '%H:%M ' .. fmt
end
end
end
elseif fmt:find('%', 1, true) then
return strftime(date, fmt, options)
return strftime(date, fmt, options)
end
end
if fmt:find('%', 1, true) then
local function hm_fmt()
return strftime(date, fmt, options)
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