Documentation for this module may be created at Module:Birthday/doc
local p = {}
D = {}
J = {}
T = {}
function BirthdayInsert(Date, Japanese, Transliterated)
table.insert(D, Date)
table.insert(J, Japanese)
table.insert(T, Transliterated)
end
--When adding, do so in the right place. It's first ordered by day, then within days by years oldest to newest.
--This way it's already in an order best for most of the birthday functions, and no sorting needs to be programmed in.
BirthdayInsert('1996-01-03', '日暮麻友', 'Higurashi Mayu')
BirthdayInsert('1998-01-15', '山下道子', 'Yamashita Michiko')
BirthdayInsert('2002-01-15', '市川月乃', 'Ichikawa Tsukino')
BirthdayInsert('1994-01-16', 'ジェニー', 'Jenny')
BirthdayInsert('2000-01-31', '松井蘭', 'Matsui Ran')
BirthdayInsert('1991-02-07', 'すき', 'Suki')
BirthdayInsert('1999-02-13', '木原ソナタ', 'Kihara Sonata')
BirthdayInsert('2004-02-21', '黒沢あかり', 'Kurosawa Akari')
BirthdayInsert('1997-02-25', '山本貞子', 'Yamamoto Sadako')
BirthdayInsert('1999-03-12', 'ジュジュ', 'Juju')
BirthdayInsert('1997-03-23', '弥海砂', 'Shaga Misa')
BirthdayInsert('2001-04-02', '桜雪', 'Sakura Yuki')
BirthdayInsert('1997-04-24', '山本麻末', 'Yamamoto Ami')
BirthdayInsert('1995-05-11', '新垣彰子', 'Niigaki Shoko')
BirthdayInsert('1993-05-25', '中村みど', 'Nakamura Mido')
BirthdayInsert('1998-06-01', '天海恵美', 'Amami Emi')
BirthdayInsert('2002-06-06', '峯岸麻里子', 'Minegishi Mariko')
BirthdayInsert('1995-06-16', '芦川彬子', 'Ashikawa Akiko')
BirthdayInsert('1998-06-20', 'キコ', 'Kiko')
BirthdayInsert('1999-06-20', '革元ちよ', 'Kawamoto Chiyo')
BirthdayInsert('1995-07-04', '堀川ミシャ', 'Hori Misha')
BirthdayInsert('1999-07-05', '小林春奈', 'Kobayashi Haruna')
BirthdayInsert('1991-07-07', '雪村笑子', 'Yukimura Emiko')
BirthdayInsert('1994-07-09', '鈴木希子', 'Suzuki Kiko')
BirthdayInsert('1995-07-16', 'レイ', 'Rae')
BirthdayInsert('1996-07-26', 'サーシャ', 'Sasha')
BirthdayInsert('1997-08-09', '高旬ありまさ', 'Koushun Arimasa')
BirthdayInsert('1992-08-16', '鈴木愛子', 'Suzuki Aiko')
BirthdayInsert('1993-08-03', '林碧麗', 'Hayashi Mirei')
BirthdayInsert('2000-09-01', '綾波さくら', 'Ayanami Sakura')
BirthdayInsert('2000-09-07', '西川ポプリ', 'Nishikawa Popuri')
BirthdayInsert('1994-09-08', '金沢マイカ', 'Kanazawa Maika')
BirthdayInsert('1997-09-17', '月村由美', 'Tsukimura Yumi')
BirthdayInsert('1997-10-02', '矢神令奈', 'Yagami Reina')
BirthdayInsert('1996-10-09', '通じ留なみい', 'Tsujiru Namii')
BirthdayInsert('1994-10-20', '山崎はるか', 'Yamasaki Haruka')
BirthdayInsert('1993-10-28', 'レミー', 'Remy')
BirthdayInsert('1996-10-29', '加嶋理香', 'Kashima Rika')
BirthdayInsert('2002-11-15', '南條由鶴', 'Nanjou Yuzuru')
BirthdayInsert('2001-11-21', '花咲美紀', 'Hanasaki Miki')
BirthdayInsert('1992-11-23', '中村倫世', 'Nakamura Tomoyo')
BirthdayInsert('1998-12-14', '黒沢由香', 'Kurosawa Yuka')
BirthdayInsert('1999-12-16', 'ミューキー', 'Miuky')
BirthdayInsert('1995-12-22', '松田七海', 'Matsuda Nanami')
function Ordinal(anumber)
if anumber % 10 == 1 then
return anumber .. "st"
elseif anumber % 10 == 2 then
if anumber%100==12 then
return anumber .. "th"
else
return anumber .. "nd"
end
elseif anumber % 10 == 3 then
if anumber%100==13 then
return anumber .. "th"
else
return anumber .. "rd"
end
else
return anumber .. "th"
end
end
function WhichBirthday(yyyymmdd)
--Just rounds to which age is nearest. For standard uses of looking forward a week, it does the trick.
_, _, y, m, d = string.find(yyyymmdd, "(%d%d%d%d)-(%d%d)-(%d%d)")
difference = os.time() - os.time{year=y, month=m, day=d}
difference = difference / 31555008
difference = math.floor(difference+0.5) --Rounding
return Ordinal(difference)
end
function WhereDayXStarts(mmdd)
i = 0
repeat
i=i+1
until string.sub( D[i], 6, 10 ) >= mmdd or i == table.getn(D)
if string.sub(D[i], 6, 10) < mmdd then i = 1 end --If we've gone all the way and found squat, stick to the beginning.
return i --.. " " .. string.sub( D[i], 6, 10 ) .. " >= " .. mmdd .. " or i == " .. table.getn(D)
end
function WhereDayXEnds(mmdd)
_, _, m, d = string.find(mmdd, "(%d%d)-(%d%d)")
if d+1 < 10 then
nextday = m .. "-0" .. d+1 --Needs zero padded
else
nextday = m .. "-" .. d+1 --Even if this date isnt' real, it should work as a point of comparison
end
if nextday=="12-32" then
return table.getn(D) -- As long as things are properly ordered, the table ends with the end of the year.
else
thisdaybegins = WhereDayXStarts(mmdd)
itbegins = WhereDayXStarts(nextday)
if(thisdaybegins==itbegins) then --Next day starts no later than today, so no need to subtract 1.
ThenWhereDayXEnds = itbegins
else
ThenWhereDayXEnds = itbegins - 1 --Just before where the next day starts, see.
if ThenWhereDayXEnds == 0 then ThenWhereDayXEnds = table.getn(D) end --Again if the very beginning is "after", the end is... the end.
end
return ThenWhereDayXEnds
end
end
function p.upcoming(frame)
num_days = tonumber(frame.args.days or 7)
num_min = tonumber(frame.args.min or 2)
starting = frame.args.starting or os.date("%m-%d",os.time()+32400)
ending = os.date("%m-%d", os.time{year=2001, month=string.sub(starting,1,2), day=string.sub(starting,4,5)}+86400*(num_days-1))
STARTBEGINS = WhereDayXStarts(starting)
ENDENDS = WhereDayXEnds(ending)
LISTEND = table.getn(D)
--output = "starting: " .. starting .. " ending: " .. ending .. " STARTBEGINS: " .. STARTBEGINS .. " ENDENDS: " .. ENDENDS .. " LISTEND: " .. LISTEND
startread2 = 0
endread2 = -1
if ENDENDS>=STARTBEGINS then
if (ENDENDS-STARTBEGINS+1) >= num_min then
--Is Y greater than X and Y-X>=Min? Fantastic! Read from spots X through Y.
--output = output .. " CASE 1 "
startread1 = STARTBEGINS
endread1 = ENDENDS
startread2 = 0
elseif (LISTEND-STARTBEGINS+1) >= num_min then
--Is Y greater than X, Y-X<Min, and End-X>=Min? OK, find what date X+Min is, find where that date ends, call it Y. Read from spots X through Y.
--output = output .. " CASE 2 "
ending = string.sub(D[STARTBEGINS+num_min-1], 6, 10 ) --mm-dd for minimum spot
ENDENDS = WhereDayXEnds(ending)
startread1 = STARTBEGINS
endread1 = ENDENDS
else
--Need more to hit minimum, rest of list isn't enough. Need to check beginning of list for end of minimum and read those too.
--output = output .. " CASE 3 "
ending = string.sub(D[num_min-(LISTEND-STARTBEGINS+1)], 6, 10 ) --mm-dd for minimum spot
ENDENDS = WhereDayXEnds(ending)
startread1 = STARTBEGINS
endread1 = LISTEND
startread2 = 1
endread2 = ENDENDS
end
else
if (LISTEND-STARTBEGINS+ENDENDS) >= num_min then
--Is Y less than X and (End-X+Y)>=Min? Read from spots X through End, then 1 through Y.
--output = output .. " CASE 4 "
startread1 = STARTBEGINS
endread1 = LISTEND
startread2 = 1
endread2 = ENDENDS
else
--Is Y less than X, (End-X+Y)<Min? OK, find what date (Min-End-X) is, find where that date ends, call it Y. Read from spots X through End, then 1 through Y.
--Very similar to an earlier case, except this time Y has already looped. Calculations should remain the same, though.
--output = output .. " CASE 5 "
ending = string.sub(D[num_min-(LISTEND-STARTBEGINS+1)], 6, 10 ) --mm-dd for minimum spot
ENDENDS = WhereDayXEnds(ending)
startread1 = STARTBEGINS
endread1 = LISTEND
startread2 = 1
endread2 = ENDENDS
end
end
--output = output .. " ending: " .. ending .. " ENDENDS: " .. ENDENDS
--output = output.. " startread1: " .. startread1 .. " " .. T[startread1] .. " endread1: " .. endread1 .. " " .. T[endread1] .. " startread2: " .. startread2 .. " endread2: " .. endread2 .. "\n"
lastday = 0
output = ""
--First read group
i = startread1
while i<= endread1 do
thisday = string.sub( D[i], 6, 10 )
if thisday ~= lastday then --It's a new day, something should be written.
output = output .. ";" .. os.date("%B %e", os.time{year=2001, month=string.sub(D[i],6,7), day=string.sub(D[i],9,10)}) .. ", "
if thisday==starting then output = output .. "Happy Birthday!" else output = output .. "Coming Soon" end
output = output .. "\n"
end
output = output .. ":[[" .. T[i] .. "]] (" .. WhichBirthday(D[i]) .. ")\n"
lastday = thisday
i=i+1
end
--Second read group
i = startread2
while i<= endread2 do
thisday = string.sub( D[i], 6, 10 )
if thisday ~= lastday then --It's a new day, something should be written.
output = output .. ";" .. os.date("%B %e", os.time{year=2001, month=string.sub(D[i],6,7), day=string.sub(D[i],9,10)}) .. ", "
if thisday==starting then output = output .. "Happy Birthday!" else output = output .. "Coming Soon" end
output = output .. "\n"
end
output = output .. ":[[" .. T[i] .. "]] (" .. WhichBirthday(D[i]) .. ")\n"
lastday = thisday
i=i+1
end
return output -- .. " " .. os.clock()
end
function p.year(frame)
year = frame.args[1] or 1982
lastday = 0
output = ""
for i=1, table.getn(D), 1 do
if string.sub(D[i],1,4) == year then
thisday = string.sub( D[i], 6, 10 )
if thisday ~= lastday then
output = output .. ";" .. os.date("%B %e", os.time{year=2001, month=string.sub(D[i],6,7), day=string.sub(D[i],9,10)}) .. "\n"
end
output = output .. ":[[" .. T[i] .. "]]\n"
lastday = thisday
end
end
return output
end
function p.month(frame)
month = frame.args[1] or 1
if month == '1' or month == '01' then
starting='01-01'
ending='02-01'
elseif month == '2' or month == '02' then
starting='02-01'
ending='03-01'
elseif month == '3' or month == '03' then
starting='03-01'
ending='04-01'
elseif month == '4' or month == '04' then
starting='04-01'
ending='05-01'
elseif month == '5' or month == '05' then
starting='05-01'
ending='06-01'
elseif month == '6' or month == '06' then
starting='06-01'
ending='07-01'
elseif month == '7' or month == '07' then
starting='07-01'
ending='08-01'
elseif month == '8' or month == '08' then
starting='08-01'
ending='09-01'
elseif month == '9' or month == '09' then
starting='09-01'
ending='10-01'
elseif month == '10' then
starting='10-01'
ending='11-01'
elseif month == '11' then
starting='11-01'
ending='12-01'
elseif month == '12' then
starting='12-01'
ending='12-31'
end
STARTBEGINS = WhereDayXStarts(starting)
--ENDENDS = WhereDayXEnds(ending)
if month=='12' then
NEXTBEGINS = table.getn(D) + 1 -- Past the end
else
NEXTBEGINS = WhereDayXStarts(ending)
end
lastday = 0
output = ""
i = STARTBEGINS
while i < NEXTBEGINS do
thisday = string.sub( D[i], 6, 10 )
if thisday ~= lastday then --It's a new day, something should be written.
output = output .. ";" .. os.date("%B %e", os.time{year=2001, month=string.sub(D[i],6,7), day=string.sub(D[i],9,10)}) .. "\n"
end
output = output .. ":[[" .. T[i] .. "]] (" .. string.sub(D[i], 1, 4) .. ")\n"
lastday = thisday
i=i+1
end
return output
end
function p.age(frame)
age = frame.args[1] or 20
output = ""
starting = os.date("%Y-%m-%d",os.time()+32400) --Y-m-d for today in Japan
_, _, y, m, d = string.find(starting, "(%d%d%d%d)-(%d%d)-(%d%d)")
LOWBORDER = y-age .. "-" .. m .. "-" .. d
if d+1<10 then --needs a leading 0
HIGHBORDER = y-age-1 .. "-" .. m .. "-0" .. d+1
else
HIGHBORDER = y-age-1 .. "-" .. m .. "-" .. d+1 --Might be an improper date, but for comparison purposes should work
end
--output = "LOWBORDER: " .. LOWBORDER .. " HIGHBORDER: " .. HIGHBORDER
--return output
STARTBEGINS = WhereDayXStarts(string.sub(HIGHBORDER,6,10))
--First half
i = STARTBEGINS
while i<= table.getn(D) do
if D[i] >= HIGHBORDER and D[i] <= LOWBORDER then
output = output .. ":[[" .. T[i] .. "]] (" .. D[i] .. ")\n"
end
i=i+1
end
--Second half
i = 1
while i<= STARTBEGINS-1 do
if D[i] >= HIGHBORDER and D[i] <= LOWBORDER then
output = output .. ":[[" .. T[i] .. "]] (" .. D[i] .. ")\n"
end
i=i+1
end
return output
end
function p.between(frame)
startdate=frame.args[1]
enddate=frame.args[2]
if startdate > enddate then --You trying to screw things up? Well, we'll just flip 'em.
temp = startdate
startdate = enddate
enddate = temp
end
output = ""
year = string.sub(startdate,1,4)
while year<=string.sub(enddate,1,4) do
if year==string.sub(startdate,1,4) then
lowcomparison = string.sub(startdate,6,10) --If it's the first year, only start at the given date
else
lowcomparison = '01-01'
end
if year==string.sub(enddate,1,4) then
highcomparison = string.sub(enddate,6,10) --If it's the last year, stop by the given date
else
highcomparison = '12-31'
end
i = 1
while i<= table.getn(D) do
if string.sub(D[i],1,4) == year and string.sub(D[i],6,10) >= lowcomparison and string.sub(D[i],6,10) <= highcomparison then
output = output .. ":[[" .. T[i] .. "]] (" .. D[i] .. ")\n"
end
i=i+1
end
year=tostring(year+1)
end
return output
end
function p.random()
math.randomseed( os.time() )
return "[[" .. T[math.random(#T)] .. "]]"
end
return p
--[[Category:Modules]]