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.

  1. 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:
  2. 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.
  3. 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.
  4. 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.
  5. Responsible use. Any risk arising from the use of information from this website is entirely the responsibility of the user.