Module:Sandbox/AlphaZeta/test3 explained

--age|12 december 1975}}

Years between two dates Result will be in these forms: "87 år" "87 eller 88 år" (range if years without month or day give) "" (if error)

= date conversion

=Date to iso-datereturns: "1975-12-31"

Date to short datereturns: "31 dec 1975"

Date to long datereturns: "31 december 1975"

= date conversion with links

returns: "[31 december|31 dec] [1975]"

returns: "[31 december] [1975]"

returns: "[31 december|31 dec] [Konstår 1975|1975]"

returns: "[31 december] [Konstår 1975|1975]"

local main = ;local months_long=local months_short=

local useEkrFkr -- flag that "e.Kr." or "f.Kr." (ED/BC) was used on input string and so should also be used in outputlocal nbsp=' '

-- split string s into an arrayfunction split(s, delimiter) result = ; for match in (s..delimiter):gmatch("(.-)"..delimiter) do table.insert(result, match); end return result;end

-- remove links from textlocal function removeLinks(text) text=string.gsub(text,"%[%[[^%[%]]-|([^%[%]|]-)%]%]","%1") -- link, text separated by "|". Handles case of File: when no alt= is specified, -assuming- last field is the legend text=string.gsub(text,"%[%[([^%[%]|]-)%]%]","%1") -- link with no funny |s at all return textend

-- remove trailing and leading whitespace from string.-- http://en.wikipedia.org/wiki/Trim_(8programming)local function trim(s) return (s:gsub("^%s*(.-)%s*$", "%1"))end

-- convert month from string to numberlocal function convertmonth(month) month = string.lower(month) for i, m in ipairs(months_long) do if m

month then return i end end for i, m in ipairs(months_short) do if m

month then return i end end return -1end

-- get max number of days in a monthlocal function daysInMonth(month) if month

2 then return 29 elseif month

4 or month

6 or month

9 or month

11 then return 30 else return 31 endend

-- takes 3 strings and returns a date object-- input:year="1999", month="12", day="31"-- output: or nil if date not validlocal function createDateObject(year,month,day,bc) local year=tonumber(year) if bc then year=-year end local month=tonumber(month) local day=tonumber(day) if year

nil or month

nil or day

nil then return nil end if month<0 or month >12 then return nil end if day<0 or day>daysInMonth(month) then return nil end return end

-- convert date string to date format-- input: a date string, example "1930 e.Kr." "1956-12-20" "12 dec 1940" "januari 2001"-- output: or nil if not validlocal function convertdate(date) local bc=false --negativ years date=removeLinks(date) date=trim(date) date=date:lower local pos pos=date:find('e%p?kr') if (pos~=nil) then useEkrFkr=true date=date:sub(1,pos-1) else pos=date:find('f%p?kr') if (pos~=nil) then useEkrFkr=true bc=true date=date:sub(1,pos-1) end end -- Check if date in numeric format (1999 or 1999-12 or 1999-12-31) if not string.match (date,"%a") then date=date:gsub(' ',) -- remove all spaces local datesplit=split(date, "-") local count=table.getn(datesplit) if count

1 then return createDateObject(datesplit[1],0,0,bc) end if count

2 then return createDateObject(datesplit[1],datesplit[2],0,bc) end if count

3 then return createDateObject(datesplit[1],datesplit[2],datesplit[3],bc) end return nil end

-- Date with written month, "31 dec(ember) 1999" or "dec(ember) 1999" date=string.gsub(date, "%s+", " ") local datesplit=split(date, " ") local count=table.getn(datesplit) if count

2 then return createDateObject(datesplit[2],convertmonth(datesplit[1]),0,bc) end if count

3 then return createDateObject(datesplit[3],convertmonth(datesplit[2]),datesplit[1],bc) end return nilend -- takes two date objects and returns number of years between them-- both dates must have year, month and daylocal function yearsBetweenDates(date1,date2) if date1.year>date2.year or (date1.year

date2.year and date1.month>date2.month) or (date1.year

date2.year and date1.month

date2.month and date1.day>date2.day) then local tmp=date1 date1=date2 date2=tmp end local years=date2.year-date1.year if date1.month>date2.month or ((date1.month

date2.month) and date1.day>date2.day) then years=years-1 end return yearsend

-- takes two date objects and returns number of years between them-- both dates must have year. Month and day are optional.local function yearsBetweenUnfixedDates(date1,date2) local date1_hi,date1_low local date2_hi,date2_low if date1.month>0 and date1.day>0 then date1_low=date1 date1_hi=date1 elseif date1.month>0 then date1_low= date1_hi= else date1_low= date1_hi= end if date2.month>0 and date2.day>0 then date2_low=date2 date2_hi=date2 elseif date2.month>0 then date2_low= date2_hi= else date2_low= date2_hi= end local years1=yearsBetweenDates(date1_low,date2_hi) local years2=yearsBetweenDates(date1_hi,date2_low) if years1

years2 then return years1 elseif years1>years2 then return years2..' eller '..years1 else return years1..' eller '..years2 endend

local function checkLinkArg(larg) if (larg

nil) then linkArg= elseif (larg:lower

'link') then linkArg='link' else local cpos=larg:find(':') if cpos~=nil then linkArg=larg:sub(cpos+1) end endend

local function createLinkText(link,text) if text

nil or text

then return elseif link

nil or link

then return text elseif link

text then return ''..text..'' else return ''..text..'' end

end

---------------------------------------------------------------------------function main.format(date,link,longFormat) local makeLinks=false local linkPrefix= -- Process link argument -- can be: nil, "", "link", "link:" or "link:Prefix" if (link

nil or link

"") then makeLinks=false elseif (link:lower

'link' or link:lower

'link:') then makeLinks=true linkPrefix= else local cpos=link:find(':') if cpos~=nil then makeLinks=true linkPrefix=link:sub(cpos+1)..' ' end end

-- Process date arguement, if any error just return it local dateObj=convertdate(date) if dateObj

nil then return date end

-- Build the date string -- date and month local result= if dateObj.month>0 then if (longFormat) then result=months_long[dateObj.month] else result=months_short[dateObj.month] end if dateObj.day>0 then result=dateObj.day..' '..result if makeLinks then result=createLinkText(dateObj.day..' '..months_long[dateObj.month],result) end end result=result..' ' end -- year local yearString,yearLink if dateObj.year<0 then yearString=(-dateObj.year)..' f.Kr.' yearLink=linkPrefix..yearString elseif useEkrFkr and dateObj.year>0 then yearString=dateObj.year..' e.Kr.' yearLink=linkPrefix..dateObj.year else yearString=dateObj.year yearLink=linkPrefix..yearString end if (not makeLinks) then result=result..yearString else result=result..createLinkText(yearLink,yearString) end

return result end

function main.yearsBetween(date1,date2) if (date1

nil or date1

) then return end if (date2

nil or date2

) then date2=os.date("%Y-%m-%d") end local dateObj1=convertdate(date1) local dateObj2=convertdate(date2) if dateObj1

nil or dateObj2

nil then return "" end return yearsBetweenUnfixedDates(dateObj1,dateObj2) ..nbsp..'år'end

function main.to_iso(input) local input_date=input.args[1] local date1=convertdate(input_date) if date1

nil then return input_date end local result=date1.year..'-' if (date1.month)<10 then result=result..'0' end result=result.. date1.month..'-' if (date1.day)<10 then result=result..'0' end result=result.. date1.day return resultend

function main.to_long(input) return main.format(input.args[1],input.args[2],true)end

function main.to_short(input) return main.format(input.args[1],input.args[2],false)end

function main.age(input) return main.yearsBetween(input.args[1],input.args[2])end return main