Module:Birthday

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('1997-07-01', '金子りえ', 'Kaneko Rie') BirthdayInsert('1995-07-02', '金澤朋子', 'Kanazawa Tomoko') BirthdayInsert('1992-07-03', '須藤茉麻', 'Sudo Maasa') BirthdayInsert('1990-07-04', '矢口めぐみ', 'Yaguchi Megumi') BirthdayInsert('1965-07-05', '小西貴雄', 'Konishi Takao') BirthdayInsert('1997-07-07', '生田衣梨奈', 'Ikuta Erina') BirthdayInsert('1985-07-11', '藤咲裕美', 'Fujisaki Hiromi') BirthdayInsert('1989-07-13', '道重さゆみ', 'Michishige Sayumi') BirthdayInsert('1991-07-13', '小倉愛実', 'Ogura Manami') BirthdayInsert('1992-07-15', '久住小春', 'Kusumi Koharu') BirthdayInsert('1984-07-17', '木村麻美', 'Kimura Asami') BirthdayInsert('2000-07-21', '田口夏実', 'Taguchi Natsumi') BirthdayInsert('1980-07-22', '北上アミ', 'Kitagami Ami') BirthdayInsert('1998-07-28', '岡村里星', 'Okamura Rise') BirthdayInsert('1989-07-23', '鍾安琪', 'Zhong An Qi') BirthdayInsert('1994-08-01', '和田彩花', 'Wada Ayaka') BirthdayInsert('1998-08-05', '鈴木香音', 'Suzuki Kanon') BirthdayInsert('1981-08-08', '飯田圭織', 'Iida Kaori') BirthdayInsert('1981-08-10', '安倍なつみ', 'Abe Natsumi') BirthdayInsert('1979-08-14', '三佳千夏', 'Miyoshi Chinatsu') BirthdayInsert('1992-08-25', '夏焼雅', 'Natsuyaki Miyabi') BirthdayInsert('1986-08-26', '川島幸', 'Kawashima Miyuki') BirthdayInsert('2001-08-26', '斎藤夏奈', 'Saito Kana') BirthdayInsert('1979-08-28', '前田有紀', 'Maeda Yuki') BirthdayInsert('1992-08-28', '趙國蓉', 'Zhao Guo Rong') BirthdayInsert('1998-08-28', '三瓶海南', 'Mikame Kana') BirthdayInsert('1999-08-29', '真城佳奈', 'Mashiro Kana') BirthdayInsert('2000-08-31', '井上ひかる', 'Inoue Hikaru') BirthdayInsert('1990-09-05', '阿部麻美', 'Abe Asami') BirthdayInsert('1983-09-06', 'ダニエル・デラウニー', 'Danielle Delaunay') BirthdayInsert('1996-09-06', '木沢留那', 'Kizawa Runa')

function Ordinal(anumber) if anumber % 10 == 1 then return anumber .. "st" elseif anumber % 10 == 2 then return anumber .. "nd" elseif anumber % 10 == 3 then return anumber .. "rd" 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 ThenWhereDayXEnds = "WhereDayXStarts(" .. nextday .. ")" itbegins = WhereDayXStarts(nextday) 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. 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? 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='01-31' elseif month == '2' or month == '02' then starting='02-01' ending='02-29' elseif month == '3' or month == '03' then starting='03-01' ending='03-31' elseif month == '4' or month == '04' then starting='04-01' ending='04-30' elseif month == '5' or month == '05' then starting='05-01' ending='05-31' elseif month == '6' or month == '06' then starting='06-01' ending='06-30' elseif month == '7' or month == '07' then starting='07-01' ending='07-31' elseif month == '8' or month == '08' then starting='08-01' ending='08-31' elseif month == '9' or month == '09' then starting='09-01' ending='09-30' elseif month == '10' then starting='10-01' ending='10-31' elseif month == '11' then starting='11-01' ending='11-30' elseif month == '12' then starting='12-01' ending='12-31' end

STARTBEGINS = WhereDayXStarts(starting) ENDENDS = WhereDayXEnds(ending)

lastday = 0 output = ""

i = STARTBEGINS while i<= ENDENDS 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

return p