Module:Date: Difference between revisions

5,802 bytes added ,  9 years ago
formatted output and strftime
(enhanced version of Module:Age which will be replaced by this module as it provides generic date functions)
 
(formatted output and strftime)
Line 45: Line 45:
local function is_leap_year(year, calname)
local function is_leap_year(year, calname)
-- Return true if year is a leap year.
-- Return true if year is a leap year.
if calname == 'JCAL' then
if calname == 'Julian' then
return year % 4 == 0
return year % 4 == 0
end
end
Line 66: Line 66:
-- 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!
-- JDN 0 is the 24-hour period starting at noon UTC on
-- JDN 0 is the 24-hour period starting at noon UTC on Monday
--    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
Line 76: Line 76:
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 == 'JCAL' then
if date.calname == 'Julian' then
offset = floor(y/4) - 32083
offset = floor(y/4) - 32083
else
else
Line 104: Line 104:
local jd = date.jd
local jd = date.jd
local limits  -- min/max limits for date ranges −9999-01-01 to 9999-12-31
local limits  -- min/max limits for date ranges −9999-01-01 to 9999-12-31
if calname == 'JCAL' then
if calname == 'Julian' then
limits = { -1931076.5, 5373557.5 }
limits = { -1931076.5, 5373557.49999 }
elseif calname == 'GCAL' then
elseif calname == 'Gregorian' then
limits = { -1930999.5, 5373484.5 }
limits = { -1930999.5, 5373484.49999 }
else
else
limits = { 1, 0 }  -- impossible
limits = { 1, 0 }  -- impossible
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
date.isvalid = false
return
return
Line 138: Line 138:
end
end
local b, c
local b, c
if calname == 'JCAL' then
if calname == 'Julian' then
b = 0
b = 0
c = jdn + 32082
c = jdn + 32082
Line 154: Line 154:
end
end


local function date_text(date)
local function make_option_table(options)
-- Return formatted string from given date.
-- If options is a string, return a table with its settings.
-- Otherwise return options (it should already be a table).
if type(options) == 'string' then
-- Example: 'am:AM era:BC'
local result = {}
for item in options:gmatch('%S+') do
local lhs, rhs = item:match('^(%w+):(.*)$')
if lhs then
result[lhs] = rhs
end
end
return result
end
return options
end
 
local function strftime(date, format, options)
-- Return date formatted as a string using codes similar to those
-- in the C strftime library function.
if not date.isvalid then
if not date.isvalid then
return '(invalid)'
return '(invalid)'
end
end
local time = ''
local codes = {
if date.hastime then
a = { field = 'dayabbr' },
if date.second > 0 then
A = { field = 'dayname' },
time = string.format(' %02d:%02d:%02d',
b = { field = 'monthabbr' },
date.hour,
B = { field = 'monthname' },
date.minute,
u = { fmt = '%d'  , field = 'dowiso' },
date.second
w = { fmt = '%d'  , field = 'dow' },
)
d = { fmt = '%02d', field = 'day' },
else
m = { fmt = '%02d', field = 'month' },
time = string.format(' %02d:%02d',
Y = { fmt = '%04d', field = 'year' },
date.hour,
H = { fmt = '%02d', field = 'hour' },
date.minute
M = { fmt = '%02d', field = 'minute' },
)
S = { fmt = '%02d', field = 'second' },