Content deleted Content added
No edit summary |
BrandonXLF (talk | contribs) Will work one soon, need this version for testing |
||
Line 1:
require ('Module:No globals')
local getArgs = require ('Module:Arguments').getArgs
local tz = {}; -- holds local copy of the specified timezone table from tz_data{}
local cfg = {}; -- for internationalization
--[[-------------------------< S E T _ S A N D B O X >--------------------------------------------------------
Weather or not to use sandbox version of data (returns /sandbox or '')
]]
local function set_sandbox (frame)
local data_sandbox;
if frame:getTitle():find('sandbox', 1, true) then
data_sandbox = true; -- bolean to toggle usage of sandbox data module when this module is in a sandbox (changeable)
else
data_sandbox = false; -- DO NOT CHANGE
end
if data_sandbox then
return '/sandbox'
else
return ''
end
end
--[[--------------------------< I S _ S E T >------------------------------------------------------------------
Line 147 ⟶ 168:
return sign * ((hours * 3600) + (minutes * 60));
else
return nil; -- we require that all timezone
end
end
Line 219 ⟶ 240:
return dst_begin, dst_end, invert;
end
Line 257 ⟶ 260:
local patterns = {
'^([%+%-±−]?)(%d%d?)(%.)(%d
'^([%+%-±−]?)(%d%d?)(:)(%d%d)$', -- two minute digits
'^([%+%-±−]?)(%d%d?)[%.:]?$', -- hours only; ignore trailing separator
Line 315 ⟶ 318:
end
--[[--------------------------< I S _ D S T _ A C T I V E >----------------------------------------------------------
Return 1 of dst is active or 0 if it's not
]]
local function is_dst_active (timestamp,utc_timestamp)
local invert; -- true when southern hemisphere
local dst_begin_ts, dst_end_ts; -- DST begin and end timestamps in UTC
if is_set (tz.dst_begins) and is_set (tz.dst_ends) and is_set (tz.dst_time) then -- make sure we have all of the parts
dst_begin_ts, dst_end_ts, invert = make_dst_timestamps (timestamp); -- get begin and end dst timestamps and invert flag
if nil == dst_begin_ts or nil == dst_end_ts then
return error_msg ('bad_dst');
end
if invert then -- southern hemisphere; use beginning and ending of standard time in the comparison
if utc_timestamp >= dst_end_ts and utc_timestamp < dst_begin_ts then -- is current date time standard time?
return 0
else
return 1
end
else -- northern hemisphere
if utc_timestamp >= dst_begin_ts and utc_timestamp < dst_end_ts then -- all timestamps are UTC
return 1
else
return 0
end
end
elseif is_set (tz.dst_begins) or is_set (tz.dst_ends) or is_set (tz.dst_time) then -- if some but not all not all parts then emit error message
return error_msg ('bad_def', args[1]:upper());
else
return 0 -- dst not observed for this timezone
end
end
--[[--------------------------< D S T _ A C T I V E >----------------------------------------------------------
Invokeable version of above. This function takes one parameter.
1. the time zone abbreviation (positional or 1=)
]]
local function dst (frame)
local args = getArgs (frame);
local data = 'Module:Time/data'..set_sandbox(frame) -- make a data module name; sandbox or live
data = mw.loadData (data); -- load the data module
cfg = data.cfg; -- get the configuration table
args[1] = args[1] or 'utc' -- default to utc
args[1] = args[1]:lower(); -- lowecase
if data['tz_aliases'][args[1]] then
args[1] = data['tz_aliases'][args[1]];
elseif data['dst_tz'][args[1]] then
args[1] = data['dst_tz'][args[1]];
end
tz = data['tz_data'][args[1]];
if not tz then
return error_msg ('unknown_tz', args[1]); -- if the timezone given isn't in module:time/data(/sandbox)
end
local os_time = os.time ()
local timestamp = os_time + get_utc_offset (); -- make local time timestamp
return is_dst_active(timestamp, os_time) -- set is_dst to 0 or 1
end
--[=[-------------------------< T I M E >----------------------------------------------------------------------
This
1. the time zone abbreviation/UTC offset (positional, always the first unnamed parameter)
2. a date format flag; second positional parameter or |df=; can have one of several values
Line 327 ⟶ 401:
7. |hide-tz = when set to 'yes' removes the timezone name
8. |unlink-tz = when set to 'yes' unlinks the timzone name
9. |
Timezone abbreviations can be found here: [[List_of_time_zone_abbreviations]]
]=]
local function time (frame)
local args = getArgs (frame); -- create the args table
local utc_timestamp, timestamp; -- current or
local tz_abbr; -- select ST or DST timezone abbreviaion used in output
local time_string; -- holds output time/date in |df= format
local utc_offset; -- true when southern hemisphere
local DF; -- date format flag; the |df= parameter
local is_dst; -- wether or not dst is active
local data = 'Module:Time/data'..set_sandbox(frame) -- make a data module name; sandbox or live
data = mw.loadData (data); -- load the data module
cfg = data.cfg; -- get the configuration table
local
local tz_aliases = {} -- create the general aliases table
local dst_table = data.dst_tz; -- get the dst aliases talbe
local aliases_table = data.tz_aliases; -- get the other aliases table
local tz_data = data.tz_data; -- get the tz data table
for k,v in pairs(dst_table) do -- add dst offsets to tz_aliases
tz_aliases[k] = v
end
for k,v in pairs(aliases_table) do -- add dst offsets to tz_aliases
tz_aliases[k] = v
end
local Timeonly = 'yes' == first_set (cfg.aliases['timeonly'], args); -- boolean
local Dateonly = 'yes' == first_set (cfg.aliases['dateonly'], args); -- boolean
Line 365 ⟶ 441:
local Unlink_tz = 'yes' == first_set (cfg.aliases['unlink-tz'], args); -- boolean
local DST = first_set (cfg.aliases['dst'], args);
if args[1] then
Line 403 ⟶ 467:
DF = first_set (cfg.aliases['df'], args) or args[2] or tz.df or cfg.default_df; -- template |df= overrides typical df from tz properties
DF = DF:lower(); -- normalize to lower case
if is_set (args.test_time) or is_set (args._TEST_TIME_) then
args.test_time = args._TEST_TIME_
end
local arg_index = {'year','month','day','hour','min','sec'} -- ISO 8601
local arguments = {['year']=nil,['month']=nil,['day']=nil,['hour']=nil,['min']=nil,['sec']=nil} -- ISO 8601
local i = 1
for val in string.gmatch(args.test_time, "%d+") do -- extract values
arguments[arg_index[i]] = val
i = i + 1
end
if not arguments.day then -- required by os.time
return error_msg ('test_time') -- return error
end
utc_timestamp = os.time(arguments); -- get timestamp of test_time
else
utc_timestamp = os.time (); -- get current server time (UTC)
end
utc_offset = get_utc_offset (); -- utc offset for specified timezone in seconds
timestamp = utc_timestamp + utc_offset; -- make local time timestamp
is_dst = is_dst_active(timestamp,utc_timestamp) -- set is_dst to 0 or 1
tz_abbr = tz.abbr; -- use standard time
elseif 'always' == DST or is_dst == 1 then -- if dst is set to always or dst is active
timestamp = timestamp + 3600; -- add a hour for dst
tz_abbr = tz.dst_abbr; -- dst abbreviation
else -- error at is_dst_active
return is_dst -- return the error
end
if args["dst_active"] then -- there's really no other module/palce to put it
if tz_abbr == tz.dst_abbr then
return '1'
else
return '0'
end
end
Line 464 ⟶ 518:
end
elseif Timeonly or DF
DF = table.concat ({'t', DF:match ('%l*(12)') or '24'}); -- |df=12, |df=24, |df=dmy12, |df=dmy24, |df=mdy12, |df=mdy24; default to t24
Line 474 ⟶ 528:
end
if not formats[DF] then
return error_msg ('bad_format', DF);
end
time_string = mw.language.getContentLanguage():formatDate (formats[DF], '@'..timestamp);
if not is_set (tz.article) then -- if some but not all not all parts then emit error message
Line 509 ⟶ 545:
});
local tz_tag = (Hide_tz and '')
return
end
Line 519 ⟶ 555:
--[[--------------------------< E X P O R T E D F U N C T I O N S >------------------------------------------
]]
return {
time = time dst = dst,
}
|