Module:Date: Difference between revisions
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 == ' | 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 == ' | 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 == ' | if calname == 'Julian' then | ||
limits = { -1931076.5, 5373557. | limits = { -1931076.5, 5373557.49999 } | ||
elseif calname == ' | elseif calname == 'Gregorian' then | ||
limits = { -1930999.5, 5373484. | 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 == ' | if calname == 'Julian' then | ||
b = 0 | b = 0 | ||
c = jdn + 32082 | c = jdn + 32082 | ||
| Line 154: | Line 154: | ||
end | end | ||
local function | local function make_option_table(options) | ||
-- Return formatted string | -- 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 | local codes = { | ||
a = { field = 'dayabbr' }, | |||
A = { field = 'dayname' }, | |||
b = { field = 'monthabbr' }, | |||
B = { field = 'monthname' }, | |||
date.minute, | u = { fmt = '%d' , field = 'dowiso' }, | ||
w = { fmt = '%d' , field = 'dow' }, | |||
d = { fmt = '%02d', field = 'day' }, | |||
m = { fmt = '%02d', field = 'month' }, | |||
Y = { fmt = '%04d', field = 'year' }, | |||
H = { fmt = '%02d', field = 'hour' }, | |||
M = { fmt = '%02d', field = 'minute' }, | |||
) | S = { fmt = '%02d', field = 'second' }, | ||