395
Bearbeitungen
(2015-07-15) |
K (32 Versionen importiert: Doku-Vorlage) |
||
(17 dazwischenliegende Versionen von 8 Benutzern werden nicht angezeigt) | |||
Zeile 1: | Zeile 1: | ||
local DateTime -- Date and time | local DateTime = { serial = "2020-04-08", | ||
local | suite = "DateTime", | ||
item = 20652535 } | |||
-- Date and time objects | |||
local Failsafe = DateTime | |||
local GlobalMod = DateTime | |||
local Calc = { } | local Calc = { } | ||
local Meta = { } | |||
local Parser = { } | local Parser = { } | ||
local Private = { } | local Private = { } | ||
Zeile 102: | Zeile 107: | ||
HST = -1000 -- Hawaiian Standard Time | HST = -1000 -- Hawaiian Standard Time | ||
} | } | ||
local foreignModule = function ( access, advanced, append, alt, alert ) | |||
-- Fetch global module | |||
-- Precondition: | |||
-- access -- string, with name of base module | |||
-- advanced -- true, for require(); else mw.loadData() | |||
-- append -- string, with subpage part, if any; or false | |||
-- alt -- number, of wikidata item of root; or false | |||
-- alert -- true, for throwing error on data problem | |||
-- Postcondition: | |||
-- Returns whatever, probably table | |||
-- 2019-10-20 | |||
local storage = access | |||
local fun, lucky, r | |||
if advanced then | |||
fun = require | |||
else | |||
fun = mw.loadData | |||
end | |||
if append then | |||
storage = string.format( "%s/%s", storage, append ) | |||
end | |||
lucky, r = pcall( fun, "Module:" .. storage ) | |||
if not lucky then | |||
local suited | |||
GlobalMod.globalModules = GlobalMod.globalModules or { } | |||
suited = GlobalMod.globalModules[ access ] | |||
if not suited and | |||
type( alt ) == "number" and | |||
alt > 0 then | |||
suited = string.format( "Q%d", alt ) | |||
suited = mw.wikibase.getSitelink( suited ) | |||
GlobalMod.globalModules[ access ] = suited or true | |||
end | |||
if type( suited ) == "string" then | |||
storage = suited | |||
if append then | |||
storage = string.format( "%s/%s", storage, append ) | |||
end | |||
lucky, r = pcall( fun, storage ) | |||
end | |||
if not lucky and alert then | |||
error( "Missing or invalid page: " .. storage, 0 ) | |||
end | |||
end | |||
return r | |||
end -- foreignModule() | |||
Zeile 123: | Zeile 177: | ||
-- Returns: | -- Returns: | ||
-- string, HTML span | -- string, HTML span | ||
local e = mw.html.create( "span" ) | |||
:addClass( "error" ) | |||
:wikitext( a ) | |||
return tostring( e ) | |||
end -- fault() | end -- fault() | ||
Zeile 137: | Zeile 194: | ||
Meta.localized = false | |||
Meta.serial = DateTime.serial | |||
Meta.signature = "__datetime" | |||
Meta.suite = "{DateTime}" | |||
Meta.components = { lang = "string", | |||
bc = "boolean", | |||
year = "number", | |||
month = "number", | |||
week = "number", | |||
dom = "number", | |||
hour = "number", | |||
min = "number", | |||
sec = "number", | |||
msec = "number", | |||
mysec = "number", | |||
zone = false, | |||
leap = "boolean", | |||
jul = "boolean" } | |||
Meta.order = { "bc", "year", "month", "week", "dom", | |||
"hour", "min", "sec", "msec", "mysec" } | |||
Meta.tableI = { -- instance metatable | |||
__index = function ( self, access ) | __index = function ( self, access ) | ||
local r = self[ | local r = self[ Meta.signature ][ access ] | ||
if r == nil then | if r == nil then | ||
if access == "serial" then | if access == "serial" then | ||
r = | r = Meta.serial | ||
elseif access == "suite" then | elseif access == "suite" then | ||
r = "DateTime" | r = "DateTime" | ||
else | else | ||
r = Prototypes[ access ] | |||
end | end | ||
end | end | ||
Zeile 158: | Zeile 230: | ||
__newindex = function ( self, access, assign ) | __newindex = function ( self, access, assign ) | ||
if type( access ) == "string" then | if type( access ) == "string" then | ||
local data = self[ | local data = self[ Meta.signature ] | ||
if assign == nil then | if assign == nil then | ||
local val = data[ access ] | local val = data[ access ] | ||
Zeile 174: | Zeile 246: | ||
end, | end, | ||
__add = function ( op1, op2 ) | __add = function ( op1, op2 ) | ||
return Prototypes.future( op1, op2 ) | return Prototypes.future( op1, op2, true ) | ||
end, | end, | ||
__eq = function ( op1, op2 ) | __eq = function ( op1, op2 ) | ||
Zeile 184: | Zeile 256: | ||
__le = function ( op1, op2 ) | __le = function ( op1, op2 ) | ||
return Prototypes.flow( op1, op2, "le" ) | return Prototypes.flow( op1, op2, "le" ) | ||
end, | |||
__tostring = function ( e ) | |||
return Prototypes.tostring( e ) | |||
end, | |||
__call = function ( func, ... ) | |||
return Meta.fiat( ... ) | |||
end | |||
} -- Meta.tableI | |||
Meta.tableL = { -- library metatable | |||
__index = function ( self, access ) | |||
local r | |||
if access == "serial" then | |||
r = Meta.serial | |||
elseif access == "suite" then | |||
r = Meta.suite | |||
end | |||
return r | |||
end, | |||
__newindex = function () | |||
return | |||
end, | |||
__tostring = function () | |||
return Meta.suite | |||
end, | |||
__call = function ( func, ... ) | |||
return Meta.fiat( ... ) | |||
end | end | ||
} | } -- Meta.tableL | ||
Meta.fiat = function ( assign, alien, add ) | |||
-- Create instance object (constructor) | |||
-- Create object (constructor) | |||
-- Parameter: | -- Parameter: | ||
-- assign -- string, with initial timestamp, or nil | -- assign -- string, with initial timestamp, or nil | ||
-- nil -- now | -- nil -- now | ||
-- false -- empty object | -- false -- empty object | ||
-- table -- clone this object, or copy from raw | |||
-- ignore remaining parameters | |||
-- alien -- string, with language code, or nil | -- alien -- string, with language code, or nil | ||
-- add -- string, with interval (PHP strtotime), or nil | -- add -- string, with interval (PHP strtotime), or nil | ||
Zeile 202: | Zeile 299: | ||
local r | local r | ||
Private.foreign() | Private.foreign() | ||
r = Private.factory( assign, alien, add ) | if type( assign ) == "table" then | ||
if assign.suite == Meta.suite and | |||
getmetatable( assign ) == Meta.tableI then | |||
r = assign[ Meta.signature ] | |||
else | |||
r = Private.from( assign ) | |||
end | |||
else | |||
r = Private.factory( assign, alien, add ) | |||
end | |||
if type( r ) == "table" then | if type( r ) == "table" then | ||
r = { [ | r = { [ Meta.signature ] = r } | ||
setmetatable( r, | setmetatable( r, Meta.tableI ) | ||
end | end | ||
return r | return r | ||
end -- DateTime | end -- Meta.fiat() | ||
setmetatable( DateTime, Meta.tableL ) | |||
DateTime.serial = nil | |||
Zeile 244: | Zeile 352: | ||
-- Parameter: | -- Parameter: | ||
-- adjust -- table, with raw numbers | -- adjust -- table, with raw numbers | ||
local ranges = { year = { min = -999, | local ranges = { year = { min = -999, | ||
max = 9999 }, | max = 9999 }, | ||
Zeile 258: | Zeile 364: | ||
msec = { mod = 1000 }, | msec = { mod = 1000 }, | ||
mysec = { mod = 1000 } } | mysec = { mod = 1000 } } | ||
local m, max, min, move, n, range | local m, max, min, move, n, range, s | ||
for | for i = 10, 2, -1 do | ||
n = adjust[ | s = Meta.order[ i ] | ||
n = adjust[ s ] | |||
if n or move then | if n or move then | ||
range = ranges[ | range = ranges[ s ] | ||
min | if range then | ||
min = range.min or 0 | |||
max = range.max or ( range.mod - 1 ) | |||
if move then | |||
n = ( n or 0 ) + move | |||
move = false | |||
end | |||
if n < min or n > max then | |||
if range.mod then | |||
m = n % range.mod | |||
move = ( n - m ) / range.mod | |||
n = min + m | |||
else -- dom | |||
if adjust.month and adjust.year and | |||
adjust.month >= 1 and | |||
adjust.month <= 12 and | |||
adjust.year > 1900 then | |||
if n > 0 then | |||
max = Calc.final( adjust ) | |||
while n > max do | |||
n = n - max | |||
if adjust.month < 12 then | |||
adjust.month = adjust.month + 1 | |||
else | |||
adjust.month = 1 | |||
adjust.year = adjust.year + 1 | |||
end | |||
max = Calc.final( adjust ) | |||
end -- while n <= max | |||
else | |||
while n < 1 do | |||
if adjust.month == 1 then | |||
adjust.month = 12 | |||
adjust.year = adjust.year - 1 | |||
else | |||
adjust.month = adjust.month - 1 | |||
end | |||
max = Calc.final( adjust ) | |||
n = n + max | |||
end -- while n < 1 | |||
end | |||
end | end | ||
end | end | ||
end | end | ||
adjust[ s ] = n | |||
end | end | ||
end | end | ||
end -- for | end -- for i | ||
end -- Calc.fair() | end -- Calc.fair() | ||
Calc.final = function ( adjust ) | |||
-- Retrieve number of days in particular month | |||
-- Parameter: | |||
-- adjust -- table, with date specification | |||
-- Returns: | |||
-- number, of days in month | |||
local r = Calc.months[ adjust.month ] | |||
if adjust.month == 2 and | |||
( adjust.year % 4 ~= 0 or | |||
adjust.year % 400 == 0 ) then | |||
r = 28 | |||
end | |||
return r | |||
end -- Calc.final() | |||
Zeile 390: | Zeile 526: | ||
if amount <= 4 then | if amount <= 4 then | ||
r.year = tonumber( analyse ) | r.year = tonumber( analyse ) | ||
elseif | elseif amount == 14 then | ||
-- timestamp | -- timestamp | ||
r.year = tonumber( analyse:sub( 1, 4 ) ) | r.year = tonumber( analyse:sub( 1, 4 ) ) | ||
r.month = tonumber( analyse:sub( 5, | r.month = tonumber( analyse:sub( 5, 6 ) ) | ||
r.dom = tonumber( analyse:sub( 7, | r.dom = tonumber( analyse:sub( 7, 8 ) ) | ||
r.hour = tonumber( analyse:sub( 9, | r.hour = tonumber( analyse:sub( 9, 10 ) ) | ||
r.min = tonumber( analyse:sub( 11, | r.min = tonumber( analyse:sub( 11, 12 ) ) | ||
r.sec = tonumber( analyse:sub( 13, | r.sec = tonumber( analyse:sub( 13, 14 ) ) | ||
else | else | ||
r = false | r = false | ||
Zeile 692: | Zeile 828: | ||
n = #s2 | n = #s2 | ||
if n <= 2 and #s3 == 4 then | if n <= 2 and #s3 == 4 then | ||
rO.dom = tonumber( | rO.dom = tonumber( s2 ) | ||
rO.year = tonumber( s3 ) | rO.year = tonumber( s3 ) | ||
rO.dom2 = ( n == 2 ) | rO.dom2 = ( n == 2 ) | ||
Zeile 1.107: | Zeile 1.243: | ||
-- analyse -- string to be interpreted | -- analyse -- string to be interpreted | ||
-- alien -- string with language code, or nil | -- alien -- string with language code, or nil | ||
-- add -- | -- add -- table, with interval, or nil | ||
-- Returns: | -- Returns: | ||
-- table, if parsed | -- table, if parsed | ||
Zeile 1.114: | Zeile 1.250: | ||
local r | local r | ||
if type( analyse ) == "string" then | if type( analyse ) == "string" then | ||
local strip = mw.ustring.char( 0x5B, 0x200E, 0x200F, 0x5D ) | |||
r = analyse:gsub( " ", " " ) | r = analyse:gsub( " ", " " ) | ||
:gsub( " ", " " ) | :gsub( " ", " " ) | ||
Zeile 1.123: | Zeile 1.260: | ||
:gsub( "%[%[", "" ) | :gsub( "%[%[", "" ) | ||
:gsub( "%]%]", "" ) | :gsub( "%]%]", "" ) | ||
:gsub( strip, "" ) | |||
r = mw.text.trim( r ) | r = mw.text.trim( r ) | ||
if r == "" then | if r == "" then | ||
r = { } | r = { } | ||
else | else | ||
local slang = ( alien or "" ) | local slang = ( alien or "" ) | ||
local parser = { en = "GermanEnglish", | |||
de = "GermanEnglish", | |||
frr = "GermanEnglish", | |||
nds = "GermanEnglish" } | |||
local suitable | |||
if slang == "" then | if slang == "" then | ||
slang = "en" | slang = "en" | ||
Zeile 1.136: | Zeile 1.279: | ||
end | end | ||
end | end | ||
slang = slang:lower() | slang = slang:lower() | ||
suitable = parser[ slang ] | |||
if suitable then | |||
local l | local l | ||
l, r = pcall( Parser | l, r = pcall( Parser[ suitable ], r ) | ||
if l and r then | if l and r then | ||
if not Prototypes.fair( r ) then | if not Prototypes.fair( r ) then | ||
Zeile 1.146: | Zeile 1.290: | ||
r = Prototypes.future( r, add ) | r = Prototypes.future( r, add ) | ||
end | end | ||
else | |||
r = "invalid format" | |||
end | end | ||
else | else | ||
r = "unknown language" | r = "unknown language: " .. slang | ||
end | end | ||
end | end | ||
Zeile 1.174: | Zeile 1.320: | ||
end | end | ||
else | else | ||
local life = false | local life = false | ||
local s, v1, v2 | local s, v1, v2 | ||
for i = | for i = 2, 10 do | ||
s = order[ i ] | s = Meta.order[ i ] | ||
v1 = at1[ s ] | v1 = at1[ s ] | ||
v2 = at2[ s ] | v2 = at2[ s ] | ||
Zeile 1.215: | Zeile 1.359: | ||
Private.foreign = function () | Private.foreign = function () | ||
-- Retrieve localization submodule | -- Retrieve localization submodule | ||
if not | if not Meta.localized then | ||
local | local d = foreignModule( DateTime.suite, | ||
if | false, | ||
"local", | |||
DateTime.item ) | |||
if type( d ) == "table" then | |||
local wk | local wk | ||
if d.slang then | if d.slang then | ||
Meta.suite = string.format( "%s %s", | |||
Meta.suite, d.slang ) | |||
World.slang = d.slang | World.slang = d.slang | ||
end | end | ||
Zeile 1.233: | Zeile 1.382: | ||
end -- for k, v | end -- for k, v | ||
end | end | ||
Meta.localized = true | |||
end | end | ||
end -- Private.foreign() | end -- Private.foreign() | ||
Private.from = function ( attempt ) | |||
-- Create valid raw table from arbitrary table | |||
-- Parameter: | |||
-- attempt -- table, to be evaluated | |||
-- Returns: | |||
-- table, with valid components, or nil | |||
local data = { } | |||
local r | |||
for k, v in pairs( Meta.components ) do | |||
if v then | |||
v = ( type( attempt[ k ] ) == v ) | |||
else | |||
v = true | |||
end | |||
if v then | |||
data[ k ] = attempt[ k ] | |||
end | |||
end -- for k, v | |||
if Prototypes.fair( data ) then | |||
r = data | |||
end | |||
return r | |||
end -- Private.from() | |||
Zeile 1.244: | Zeile 1.419: | ||
-- add -- string or number, to be added | -- add -- string or number, to be added | ||
-- Returns: | -- Returns: | ||
-- | -- table, with shift, or false/nil | ||
local r | local r | ||
if add then | if add then | ||
Zeile 1.251: | Zeile 1.426: | ||
r = tonumber( add ) | r = tonumber( add ) | ||
s = "number" | s = "number" | ||
end | end | ||
if s == "number" then | if s == "number" then | ||
Zeile 1.258: | Zeile 1.431: | ||
r = false | r = false | ||
else | else | ||
r = string.format( "%d second", r ) | r = string.format( "%d second", r or add ) | ||
end | end | ||
elseif s | elseif s == "string" then | ||
r = add | |||
else | |||
r = false | r = false | ||
end | end | ||
Zeile 1.269: | Zeile 1.444: | ||
return r | return r | ||
end -- Private.future() | end -- Private.future() | ||
Prototypes.clone = function ( self ) | |||
-- Clone object | |||
-- Parameter: | |||
-- self -- table, with object, to be cloned | |||
-- Returns: | |||
-- table, with object | |||
local r = { [ Meta.signature ] = self[ Meta.signature ] } | |||
setmetatable( r, Meta.tableI ) | |||
return r | |||
end -- Prototypes.clone() | |||
Prototypes.failsafe = function ( self, atleast ) | |||
-- Retrieve versioning and check for compliance | |||
-- Precondition: | |||
-- atleast -- string, with required version or "wikidata" or "~" | |||
-- or false | |||
-- Postcondition: | |||
-- Returns string -- with queried version, also if problem | |||
-- false -- if appropriate | |||
local last = ( atleast == "~" ) | |||
local since = atleast | |||
local r | |||
if last or since == "wikidata" then | |||
local item = Meta.item | |||
since = false | |||
if type( item ) == "number" and item > 0 then | |||
local entity = mw.wikibase.getEntity( string.format( "Q%d", | |||
item ) ) | |||
if type( entity ) == "table" then | |||
local seek = Failsafe.serialProperty or "P348" | |||
local vsn = entity:formatPropertyValues( seek ) | |||
if type( vsn ) == "table" and | |||
type( vsn.value ) == "string" and | |||
vsn.value ~= "" then | |||
if last and | |||
vsn.value == ( Meta.serial or DateTime.serial ) then | |||
r = false | |||
else | |||
r = vsn.value | |||
end | |||
end | |||
end | |||
end | |||
end | |||
if type( r ) == "nil" then | |||
if not since or since <= Meta.serial then | |||
r = Meta.serial | |||
else | |||
r = false | |||
end | |||
end | |||
return r | |||
end -- Prototypes.failsafe() | |||
Zeile 1.347: | Zeile 1.580: | ||
end | end | ||
if d == 29 and m == 2 and y then | if d == 29 and m == 2 and y then | ||
if y % 4 ~= 0 | if y % 4 ~= 0 or | ||
( y % 100 == 0 and | |||
y % 400 ~= 0 ) then | |||
ret = false | ret = false | ||
end | end | ||
Zeile 1.399: | Zeile 1.634: | ||
end | end | ||
else | else | ||
local life = false | local life = false | ||
local leak = false | local leak = false | ||
local s, v | local s, v | ||
for i = 1, 10 do | for i = 1, 10 do | ||
s = order[ i ] | s = Meta.order[ i ] | ||
v = self[ s ] | v = self[ s ] | ||
if v then | if v then | ||
Zeile 1.492: | Zeile 1.725: | ||
Prototypes. | Prototypes.fix = function ( self ) | ||
-- | -- Adapt this object to local time if no explicit zone given | ||
-- Parameter: | -- Parameter: | ||
-- self -- table, with numbers etc. | -- self -- table, with numbers etc. | ||
if type( self ) == "table" and | |||
not self.zone then | |||
local seconds = Prototypes.format( self, "Z" ) | |||
Prototypes.future( self, - tonumber( seconds ) ) | |||
end | |||
end -- Prototypes.fix() | |||
Prototypes.flow = function ( self, another, assert ) | |||
-- Compare this object with another timestamp | |||
-- Parameter: | |||
-- self -- table, with numbers etc. | |||
-- another -- DateTime or string or nil (now) | -- another -- DateTime or string or nil (now) | ||
-- assert -- nil, or string with operator | -- assert -- nil, or string with operator | ||
Zeile 1.504: | Zeile 1.750: | ||
-- else: -1, 0, 1 | -- else: -1, 0, 1 | ||
-- nil if invalid | -- nil if invalid | ||
local r | local base, other, r | ||
if type( self ) == "table" then | if type( self ) == "table" then | ||
base = self | |||
other = another | |||
elseif type( another ) == "table" then | |||
base = another | |||
other = self | |||
end | |||
if base then | |||
if type( other ) ~= "table" then | |||
other = Meta.fiat( other ) | |||
end | end | ||
if type( | if type( other ) == "table" then | ||
r = Private.flow( | r = Private.flow( base, other ) | ||
if r and type( assert ) == "string" then | if r and type( assert ) == "string" then | ||
local trsl = { lt = "<", | local trsl = { lt = "<", | ||
Zeile 1.562: | Zeile 1.812: | ||
local r = false | local r = false | ||
if type( self ) == "table" then | if type( self ) == "table" then | ||
local opts = { lang = | local slang = self.lang or "en" | ||
local babel | local opts = { lang = slang } | ||
local babel | |||
if type( adapt ) == "table" then | if type( adapt ) == "table" then | ||
if type( adapt.lang ) == "string" then | if type( adapt.lang ) == "string" then | ||
local i = adapt.lang:find( "-", 3, true ) | local i = adapt.lang:find( "-", 3, true ) | ||
if i then | if i then | ||
slang = adapt.lang | slang = adapt.lang:lower() | ||
opts.lang = slang:sub( 1, i - 1 ) | opts.lang = slang:sub( 1, i - 1 ) | ||
else | else | ||
opts.lang = adapt.lang | opts.lang = adapt.lang:lower() | ||
end | end | ||
end | end | ||
opts.london = adapt.london | opts.london = adapt.london | ||
opts.lonely = adapt.lonely | opts.lonely = adapt.lonely | ||
end | end | ||
babel = mw.language.new( opts.lang ) | babel = mw.language.new( opts.lang:lower() ) | ||
if babel then | if babel then | ||
local shift, show, stamp, suffix, limit4, locally | local shift, show, stamp, suffix, limit4, locally | ||
Zeile 1.589: | Zeile 1.839: | ||
stamp = string.format( "%d %s", self.dom, stamp ) | stamp = string.format( "%d %s", self.dom, stamp ) | ||
end | end | ||
if ask and ask:find( "Mon4" ) then | if ask and ask:find( "Mon4", 1, true ) then | ||
local mon4 = World.months4[ opts.lang ] | local mon4 = World.months4[ opts.lang:lower() ] | ||
if mon4 | if mon4 and mon4[ self.month ] then | ||
limit4 = true | |||
end | end | ||
end | end | ||
Zeile 1.601: | Zeile 1.849: | ||
end | end | ||
if self.hour then | if self.hour then | ||
stamp = string.format( "%s %02d:", stamp, self.hour ) | if stamp then | ||
stamp = stamp .. " " | |||
else | |||
stamp = "" | |||
end | |||
stamp = string.format( "%s%02d:", stamp, self.hour ) | |||
if self.min then | if self.min then | ||
stamp = string.format( "%s%02d", stamp, self.min ) | stamp = string.format( "%s%02d", stamp, self.min ) | ||
Zeile 1.641: | Zeile 1.894: | ||
if self.month then | if self.month then | ||
local bucket, m, suite, x | local bucket, m, suite, x | ||
if show:find( "F" ) then | if show:find( "F", 1, true ) then | ||
suite = "monthsLong" | suite = "monthsLong" | ||
elseif show:find( "M" ) then | elseif show:find( "M", 1, true ) then | ||
suite = "monthsAbbr" | suite = "monthsAbbr" | ||
end | end | ||
bucket = World[ suite ] | bucket = World[ suite ] | ||
if bucket then | if bucket then | ||
m = bucket[ opts.lang ] | m = bucket[ opts.lang:lower() ] | ||
if slang then | if slang then | ||
x = bucket[ slang ] | x = bucket[ slang:lower() ] | ||
end | end | ||
if m then | if m then | ||
Zeile 1.713: | Zeile 1.966: | ||
Prototypes.future = function ( self, add ) | Prototypes.future = function ( self, add, allocate ) | ||
-- Relative move by interval | -- Relative move by interval | ||
-- Parameter: | -- Parameter: | ||
-- self | -- self -- table, to be used as base | ||
-- add | -- add -- string or number, to be added | ||
-- allocate -- true, if a clone shall be returned | |||
-- Returns: | -- Returns: | ||
-- table, with shift | -- table, with shift | ||
Zeile 1.723: | Zeile 1.977: | ||
if type( self ) == "table" then | if type( self ) == "table" then | ||
r = self | r = self | ||
shift = add | shift = add | ||
elseif type( add ) == "table" then | elseif type( add ) == "table" then | ||
r = add | r = add | ||
shift = self | shift = self | ||
end | end | ||
if r then | if r then | ||
raw = r[ | if r[ Meta.signature ] then | ||
rel = Private.future( shift ) | raw = r[ Meta.signature ] | ||
else | |||
raw = r | |||
end | |||
if type( shift ) == "table" then | |||
rel = shift | |||
else | |||
rel = Private.future( shift ) | |||
end | |||
end | end | ||
if raw and rel then | if raw and rel then | ||
if allocate then | |||
r = Prototypes.clone( r ) | |||
raw = r[ Meta.signature ] | |||
end | |||
for k, v in pairs( rel ) do | for k, v in pairs( rel ) do | ||
raw[ k ] = ( raw[ k ] or 0 ) + v | raw[ k ] = ( raw[ k ] or 0 ) + v | ||
end -- for k, v | end -- for k, v | ||
Calc.fair( raw ) | Calc.fair( raw ) | ||
r[ Meta.signature ] = raw | |||
end | end | ||
return r | return r | ||
end -- Prototypes.future() | end -- Prototypes.future() | ||
Prototypes.tostring = function ( self ) | |||
-- Stringify yourself | |||
-- Parameter: | |||
-- self -- table, to be stringified | |||
-- Returns: | |||
-- string | |||
local dels = { false, "", "-", "-", "", "", ":", ":", ".", "" } | |||
local wids = { false, 4, 2, 2, 2, 2, 2, 2, 3, 3 } | |||
local s = "" | |||
local n, r, spec | |||
local f = function ( a ) | |||
n = self[ Meta.order[ a ] ] | |||
s = s .. dels[ a ] | |||
if n then | |||
spec = string.format( "%%s%%0%dd", wids[ a ] ) | |||
s = string.format( spec, s, n ) | |||
end | |||
end -- f() | |||
for i = 2, 5 do | |||
f( i ) | |||
end -- for i | |||
r = s | |||
s = "" | |||
for i = 6, 10 do | |||
f( i ) | |||
end -- for i | |||
if s == "::." then | |||
r = r:gsub( "%-+$", "" ) | |||
else | |||
if r == "--" then | |||
r = s | |||
else | |||
r = string.format( "%sT%s", r, s ) | |||
end | |||
end | |||
r = r:gsub( "%.$", "" ) | |||
return r | |||
end -- Prototypes.tostring() | |||
Prototypes.valueOf = function ( self ) | |||
-- Returns yourselves primitive value (primitive table) | |||
-- Parameter: | |||
-- self -- table, to be dumped | |||
-- Returns: | |||
-- table, or false | |||
local r | |||
if type( self ) == "table" then | |||
r = self[ Meta.signature ] | |||
end | |||
return r or false | |||
end -- Prototypes.valueOf() | |||
Zeile 1.768: | Zeile 2.091: | ||
Frame = frame | Frame = frame | ||
l, r = pcall( Prototypes.flow, | l, r = pcall( Prototypes.flow, | ||
Meta.fiat( s1 ), s2, action ) | |||
if r == true then | if r == true then | ||
r = "1" | r = "1" | ||
Zeile 1.792: | Zeile 2.115: | ||
if not ask or ask == "" then | if not ask or ask == "" then | ||
r1 = "c" | r1 = "c" | ||
elseif ask == "*" then | |||
if World.present then | |||
if assigned.hour then | |||
if assigned.dom or assigned.month or assigned.year then | |||
if World.present.both and | |||
World.present.date and | |||
World.present.time then | |||
r1 = World.present.both | |||
:gsub( "$date", World.present.date ) | |||
:gsub( "$time", World.present.time ) | |||
else | |||
r1 = World.present.date | |||
end | |||
end | |||
r1 = r1 or World.present.time | |||
else | |||
r1 = World.present.date | |||
end | |||
end | |||
r1 = r1 or "c" | |||
else | else | ||
local template = World.templates[ ask ] | local template = World.templates[ ask ] | ||
Zeile 1.800: | Zeile 2.143: | ||
if tmp then | if tmp then | ||
template = tmp[ ask ] | template = tmp[ ask ] | ||
end | |||
if not template then | |||
local i = slang:find( "-", 3, true ) | |||
if i then | |||
slang = slang:sub( 1, i - 1 ):lower() | |||
tmp = World.templates[ slang ] | |||
if tmp then | |||
template = tmp[ ask ] | |||
end | |||
end | |||
end | end | ||
end | end | ||
Zeile 1.821: | Zeile 2.174: | ||
end | end | ||
if template.lift and | if template.lift and | ||
(assigned.dom or | ( assigned.dom or | ||
not ( assigned.month or assigned.year or assigned.bc ) | |||
) then | ) then | ||
local stamp = false | local stamp = false | ||
Zeile 1.845: | Zeile 2.198: | ||
end | end | ||
end | end | ||
if low or ask:find( "hh:mm:ss" ) then | if low or ask:find( "hh:mm:ss", 1, true ) then | ||
if stamp then | if stamp then | ||
r1 = string.format( "%s %s", r1, stamp ) | r1 = string.format( "%s %s", r1, stamp ) | ||
Zeile 1.901: | Zeile 2.254: | ||
if #s == 1 then | if #s == 1 then | ||
-- "YXWVUTSRQPONZABCDEFGHIKLM" | -- "YXWVUTSRQPONZABCDEFGHIKLM" | ||
move = World.zones[ "!" ]:find( s ) | move = World.zones[ "!" ]:find( s, 1, true ) | ||
if move then | if move then | ||
move = ( move - 13 ) * 100 | move = ( move - 13 ) * 100 | ||
Zeile 1.916: | Zeile 2.269: | ||
if tmp then | if tmp then | ||
code = tmp[ s ] | code = tmp[ s ] | ||
end | |||
if not code and | |||
slang ~= "en" and | |||
World.zones.en then | |||
code = World.zones.en[ s ] | |||
end | end | ||
end | end | ||
Zeile 1.972: | Zeile 2.330: | ||
local p = { } | local p = { } | ||
function p.test( args ) | function p.test( args, alien ) | ||
local slang = args | local slang = args.lang or alien | ||
local obj = | local obj = Meta.fiat( args[ 1 ], false, args.shift ) | ||
local r | local r | ||
if type( obj ) == "table" then | if type( obj ) == "table" then | ||
Zeile 1.989: | Zeile 2.347: | ||
r = ( args.noerror or "0" ) | r = ( args.noerror or "0" ) | ||
if r == "0" then | if r == "0" then | ||
r = fault( "Format | r = fault( "Format invalid" ) | ||
else | else | ||
r = "" | r = "" | ||
Zeile 2.000: | Zeile 2.358: | ||
function p.failsafe( frame ) | function p.failsafe( frame ) | ||
local since = frame.args[ 1 ] | local s = type( frame ) | ||
local r, since | |||
if s == "table" then | |||
since = frame.args[ 1 ] | |||
elseif s == "string" then | |||
since = mw.text.trim( since ) | since = mw.text.trim( since ) | ||
if since == "" then | if since == "" then | ||
since = false | |||
end | end | ||
end | end | ||
return Prototypes.failsafe( false, since ) or "" | |||
end -- p.failsafe | end -- p.failsafe | ||
Zeile 2.023: | Zeile 2.374: | ||
function p.format( frame ) | function p.format( frame ) | ||
-- 1 | -- 1 -- stamp | ||
-- 2 | -- 2 -- spec | ||
-- | -- lang | ||
-- | -- shift | ||
-- noerror | |||
local l, r | local l, r | ||
local v = { frame.args[ 1 ], | local v = { frame.args[ 1 ], | ||
frame.args[ 2 ], | frame.args[ 2 ], | ||
frame.args | shift = frame.args.shift, | ||
noerror = frame.args.noerror } | noerror = frame.args.noerror } | ||
if not v[ 1 ] or v[ 1 ] == "now" then | if not v[ 1 ] or v[ 1 ] == "now" then | ||
v[ 1 ] = frame:callParserFunction( "#timel", "c", v | v[ 1 ] = frame:callParserFunction( "#timel", "c", v.shift ) | ||
v | v.shift = false | ||
end | end | ||
Frame = frame | Frame = frame | ||
l, r = pcall( p.test, v ) | l, r = pcall( p.test, v, frame.args[ 3 ] or frame.args.lang ) | ||
if not l then | if not l then | ||
r = fault( r ) | r = fault( r ) | ||
Zeile 2.068: | Zeile 2.419: | ||
p.DateTime = function ( | p.DateTime = function () | ||
return DateTime | return DateTime | ||
end -- p.DateTime | end -- p.DateTime | ||
return p | return p |