Modul:DateTime: Unterschied zwischen den Versionen
2015-08-03
(2015-07-15) |
(2015-08-03) |
||
Zeile 1: | Zeile 1: | ||
local DateTime | local DateTime = { serial = "2015-08-03" } -- Date and time objects | ||
local Calc = { } | local Calc = { } | ||
local Meta = { } | |||
local Parser = { } | local Parser = { } | ||
local Private = { } | local Private = { } | ||
Zeile 137: | Zeile 137: | ||
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 173: | ||
__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 189: | ||
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 199: | ||
__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 | end | ||
} | } -- Meta.tableI | ||
Meta.tableL = { -- library metatable | |||
__index = function ( self, access ) | |||
local r | |||
if access == "serial" then | |||
-- Create object (constructor) | 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 | |||
} -- Meta.tableL | |||
Meta.fiat = function ( assign, alien, add ) | |||
-- Create instance 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 242: | ||
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 295: | ||
-- 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 307: | ||
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 = range.min or 0 | min = range.min or 0 | ||
max = range.max or ( range.mod - 1 ) | max = range.max or ( range.mod - 1 ) | ||
Zeile 296: | Zeile 346: | ||
end | end | ||
end | end | ||
adjust[ | adjust[ s ] = n | ||
end | end | ||
end -- for | end -- for i | ||
end -- Calc.fair() | end -- Calc.fair() | ||
Zeile 1.174: | Zeile 1.224: | ||
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.263: | ||
Private.foreign = function () | Private.foreign = function () | ||
-- Retrieve localization submodule | -- Retrieve localization submodule | ||
if not | if not Meta.localized then | ||
local l, d = pcall( mw.loadData, "Module:DateTime/local" ) | local l, d = pcall( mw.loadData, "Module:DateTime/local" ) | ||
if l then | if l 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.227: | Zeile 1.277: | ||
for subk, subv in pairs( v ) do | for subk, subv in pairs( v ) do | ||
wk[ subk ] = subv | wk[ subk ] = subv | ||
end -- for k, v | end -- for k, v%s %s | ||
else | else | ||
World[ k ] = v | World[ k ] = v | ||
Zeile 1.233: | Zeile 1.283: | ||
end -- for k, v | end -- for k, v | ||
end | end | ||
Meta.localized = true | |||
end | end | ||
end -- Private.foreign() | end -- Private.foreign() | ||
Zeile 1.239: | Zeile 1.289: | ||
Private. | Private.from = function ( attempt ) | ||
-- | -- Create valid raw table from arbitrary table | ||
-- Parameter: | -- Parameter: | ||
-- | -- attempt -- table, to be evaluated | ||
-- Returns: | -- Returns: | ||
-- | -- table, with valid components, or nil | ||
local data = { } | |||
local r | local r | ||
for k, v in pairs( Meta.components ) do | |||
if v then | |||
if | v = ( type( attempt[ k ] ) == v ) | ||
else | else | ||
r = add | 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() | |||
Private.future = function ( add ) | |||
-- Normalize move interval | |||
-- Parameter: | |||
-- add -- string or number, to be added | |||
-- Returns: | |||
-- string, with shift, or false/nil | |||
local r | |||
if add then | |||
local s = type( add ) | |||
if s == "string" and add:match( "^%s*[+-]?%d+%.?%d*%s*$" ) then | |||
r = tonumber( add ) | |||
s = "number" | |||
else | |||
r = add | |||
end | end | ||
if s == "number" then | if s == "number" then | ||
Zeile 1.269: | Zeile 1.345: | ||
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() | |||
Zeile 1.399: | Zeile 1.488: | ||
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.504: | Zeile 1.591: | ||
-- 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.713: | Zeile 1.804: | ||
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.815: | ||
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[ | raw = r[ Meta.signature ] | ||
rel = Private.future( shift ) | rel = Private.future( shift ) | ||
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, 4 do | |||
f( i ) | |||
end -- for i | |||
r = s | |||
s = "" | |||
for i = 5, 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 | |||
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 1.920: | ||
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.973: | Zeile 2.125: | ||
function p.test( args ) | function p.test( args ) | ||
local slang = args | local slang = args.lang | ||
local obj = | local obj = Meta.fiat( args[ 1 ], slang or "de", args.shift ) | ||
local r | local r | ||
if type( obj ) == "table" then | if type( obj ) == "table" then | ||
Zeile 2.009: | Zeile 2.161: | ||
end | end | ||
if since then | if since then | ||
if since > | if since > Meta.serial then | ||
r = "" | r = "" | ||
else | else | ||
r = | r = Meta.serial | ||
end | end | ||
else | else | ||
r = | r = Meta.serial | ||
end | end | ||
return r | return r | ||
Zeile 2.023: | Zeile 2.175: | ||
function p.format( frame ) | function p.format( frame ) | ||
-- 1 | -- 1 -- stamp | ||
-- 2 | -- 2 -- spec | ||
-- 3 | -- 3 -- slang *LEGACY* | ||
-- | -- 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[ 3 ], | lang = frame.args[ 3 ] or frame.args.lang, | ||
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 | ||
Zeile 2.068: | Zeile 2.222: | ||
p.DateTime = function ( | p.DateTime = function () | ||
return DateTime | return DateTime | ||
end -- p.DateTime | end -- p.DateTime | ||
return p | return p |