Module:Sandbox/AlphaZeta/test3
--[[
Calculates years between two dates, for example birth date and death date.
Input dates can be in any of these formats:
"1999-12-31"
"1999-12"
"1999"
"31 december 1999"
"31 dec 1999"
"december 1999"
"dec 1999"
also dates with links are accepted, ie "[31 december] [1999]"
case doesnt matter, "31 DECEMBER 1999"
"f.Kr." (BC) and "e.Kr." (AD) allowed, ie "300 f.Kr."
Usage:
====== age ======================================
Years between now and a date
{{#DateHelper|age|12 december 1975}}
Years between two dates
{{#DateHelper|age|12 december 1975|1 januari 2003}}
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-date
{{#DateHelper|to_iso|31 december 1975}}
returns: "1975-12-31"
Date to short date
{{#DateHelper|to_short|1975-12-31}}
returns: "31 dec 1975"
Date to long date
{{#DateHelper|to_long|1975-12-31}}
returns: "31 december 1975"
====== date conversion with links ===============
{{#DateHelper|to_short|1975-12-31|link}}
returns: "[31 december|31 dec] [1975]"
{{#DateHelper|to_long|1975-12-31|link}}
returns: "[31 december] [1975]"
{{#DateHelper|to_short|1975-12-31|link}}
returns: "[31 december|31 dec] [Konstår 1975|1975]"
{{#DateHelper|to_long|1975-12-31|link:Konstår}}
returns: "[31 december] [Konstår 1975|1975]"
]]
local main = {};
local months_long={'januari','februari','mars','april','maj','juni','juli','augusti','september','oktober','november','december'}
local months_short={'jan','feb','mar','apr','maj','jun','jul','aug','sep','okt','nov','dec'}
local useEkrFkr -- flag that "e.Kr." or "f.Kr." (ED/BC) was used on input string and so should also be used in output
local nbsp=' '
-- split string s into an array
function split(s, delimiter)
result = {};
for match in (s..delimiter):gmatch("(.-)"..delimiter) do
table.insert(result, match);
end
return result;
end
-- remove links from text
local 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 text
end
-- 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 number
local 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 -1
end
-- get max number of days in a month
local 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
end
end
-- takes 3 strings and returns a date object
-- input:year="1999", month="12", day="31"
-- output: {year=1999,month=12,day=31} or nil if date not valid
local 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 {year=year,month=month,day=day}
end
-- convert date string to date format
-- input: a date string, example "1930 e.Kr." "1956-12-20" "12 dec 1940" "januari 2001"
-- output: {year=1999,month=12,day=31} or nil if not valid
local 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 nil
end
-- takes two date objects and returns number of years between them
-- both dates must have year, month and day
local 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 years
end
-- 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={year=date1.year,month=date1.month,day=1}
date1_hi={year=date1.year,month=date1.month,day=daysInMonth(date1.month)}
else
date1_low={year=date1.year,month=1,day=1}
date1_hi={year=date1.year,month=12,day=31}
end
if date2.month>0 and date2.day>0 then
date2_low=date2
date2_hi=date2
elseif date2.month>0 then
date2_low={year=date2.year,month=date2.month,day=1}
date2_hi={year=date2.year,month=date2.month,day=daysInMonth(date2.month)}
else
date2_low={year=date2.year,month=1,day=1}
date2_hi={year=date2.year,month=12,day=31}
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
end
end
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
end
end
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 '[['..link..'|'..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 result
end
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
Content Disclaimer
Informasi ini disarikan dari Wikipedia dan disajikan kembali untuk tujuan edukasi. Konten tersedia di bawah lisensi CC BY-SA 3.0. Kami tidak bertanggung jawab atas ketidakakuratan data yang bersumber dari kontribusi publik tersebut.
- The information displayed on this website is sourced in part or in whole from Wikipedia and has been adapted for the purpose of restating it. We strive to provide accurate and relevant information, however:
- There is no guarantee of absolute accuracy. Wikipedia is an open, collaborative project that can be edited by anyone, so information is subject to change.
- It is not intended to constitute professional advice. The content displayed is for informational and educational purposes only. For important decisions (e.g., medical, legal, or financial), please consult a professional.
- Content copyright. Wikipedia is licensed under the Creative Commons Attribution-ShareAlike License (CC BY-SA). This means that content may be reused with appropriate attribution and shared under a similar license.
- Responsible use. Any risk arising from the use of information from this website is entirely the responsibility of the user.