Module:Date: Difference between revisions

928 bytes removed ,  9 years ago
major refactor, mostly working now; add/subtract with a date; remove template handling which will be in Module:Age
(tweak formatted output; extract_date to parse an input date string)
(major refactor, mostly working now; add/subtract with a date; remove template handling which will be in Module:Age)
Line 19: Line 19:


local function strip_to_nil(text)
local function strip_to_nil(text)
-- Return nil if text is nil or is an empty string after trimming.
-- If text is a string, return its trimmed content, or nil.
-- If text is a non-blank string, return its content after trimming.
-- Otherwise return text (convenient when Date fields are provided from
-- Otherwise return text (convenient when accessed via another module).
-- another module which is able to pass, for example, a number).
if type(text) == 'string' then
if type(text) == 'string' then
local result = text:match("^%s*(.-)%s*$")
text = text:match('(%S.-)%s*$')
if result == '' then
return nil
end
return result
end
if text == nil then
return nil
end
end
return text
return text
Line 63: Line 56:
-- Return jd, jdz from a Julian or Gregorian calendar date where
-- Return jd, jdz from a Julian or Gregorian calendar date where
--  jd = Julian date and its fractional part is zero at noon
--  jd = Julian date and its fractional part is zero at noon
--  jdz = similar, but fractional part is zero at 00:00:00
--  jdz = same, but assume time is 00:00:00 if no time given
-- http://www.tondering.dk/claus/cal/julperiod.php#formula
-- http://www.tondering.dk/claus/cal/julperiod.php#formula
-- Testing shows this works for all dates from year -9999 to 9999!
-- Testing shows this works for all dates from year -9999 to 9999!
Line 69: Line 62:
--    1 January 4713 BC  = (-4712, 1, 1)  Julian calendar
--    1 January 4713 BC  = (-4712, 1, 1)  Julian calendar
--  24 November 4714 BC = (-4713, 11, 24) Gregorian calendar
--  24 November 4714 BC = (-4713, 11, 24) Gregorian calendar
if not date.isvalid then
return 0, 0  -- always return numbers to simplify usage
end
local floor = math.floor
local floor = math.floor
local offset
local offset
Line 82: Line 72:
end
end
local m = date.month + 12*a - 3
local m = date.month + 12*a - 3
local date_part = date.day + floor((153*m + 2)/5) + 365*y + offset
local jd = date.day + floor((153*m + 2)/5) + 365*y + offset
local time_part, zbias
if date.hastime then
if date.hastime then
time_part = (date.hour + (date.minute + date.second / 60) /60) / 24 - 0.5
jd = jd + (date.hour + (date.minute + date.second / 60) /60) / 24 - 0.5
zbias = 0
return jd, jd
else
time_part = 0
zbias = -0.5
end
end
local jd = date_part + time_part
return jd, jd - 0.5
return jd, jd + zbias
end
end


local function set_date_from_jd(date)
local function set_date_from_jd(date)
-- Set the fields of table date from its Julian date field.
-- Set the fields of table date from its Julian date field.
-- Return true if date is valid.
-- http://www.tondering.dk/claus/cal/julperiod.php#formula
-- http://www.tondering.dk/claus/cal/julperiod.php#formula
-- This handles the proleptic Julian and Gregorian calendars.
-- This handles the proleptic Julian and Gregorian calendars.
Line 112: Line 98:
end
end
if not (limits[1] <= jd and jd <= limits[2]) then
if not (limits[1] <= jd and jd <= limits[2]) then
date.isvalid = false
return
return
end
end
date.isvalid = true
local jdn = floor(jd)
local jdn = floor(jd)
if date.hastime then
if date.hastime then
Line 152: Line 136:
date.month = m + 3 - 12*floor(m/10)
date.month = m + 3 - 12*floor(m/10)
date.year = 100*b + d - 4800 + floor(m/10)
date.year = 100*b + d - 4800 + floor(m/10)
return true
end
end


Line 189: Line 174:
date.minute = M  -- 0 to 59
date.minute = M  -- 0 to 59
date.second = S  -- 0 to 59
date.second = S  -- 0 to 59
date.isvalid = true
if type(options) == 'table' then
if type(options) == 'table' then
for _, k in ipairs({ 'am', 'era' }) do
for _, k in ipairs({ 'am', 'era' }) do
Line 200: Line 184:
end
end


local function make_option_table(options)
local function make_option_table(options1, options2)
-- If options is a string, return a table with its settings.
-- If options1 is a string, return a table with its settings, or
-- Otherwise return options (it should already be a table).
-- if it is a table, use its settings.
if type(