Marvel Database
No edit summary
No edit summary
(46 intermediate revisions by the same user not shown)
Line 4: Line 4:
 
local getArgs = require('Dev:Arguments').getArgs
 
local getArgs = require('Dev:Arguments').getArgs
 
local language = mw.language.new('en')
 
local language = mw.language.new('en')
local monthAliases = monthData[1]
+
local month_names = monthData[1]
local monthNumbers = monthData[2]
+
local month_numbers = monthData[2]
  +
local days_in_month = {31,28,31,30,31,30,31,31,30,31,30,31}
 
   
  +
--------------------------------------------------------------------------------
 
-- return full month name
 
-- return full month name
function p.month(frame)
+
function p.get_month_name(frame)
 
local args = getArgs(frame)
 
local args = getArgs(frame)
local name = mw.text.trim(args[1])
+
local name = args[1]
local output = monthAliases[ string.lower(name) ]
+
local output = nil
  +
return output or name
 
  +
if not h.isempty(name)
  +
then
  +
name = mw.text.trim(name)
  +
name = string.gsub(name, '^0', '')
  +
output = month_names[ string.lower(name) ]
  +
end
  +
  +
return output
 
end
 
end
   
   
  +
--------------------------------------------------------------------------------
 
-- return month number
 
-- return month number
function p.monthNumber(frame)
+
function p.get_month_number(frame)
local args = getArgs(frame)
+
local args = getArgs(frame)
local number = mw.text.trim(args[1])
+
local number = args[1]
local output = monthNumbers[ string.lower(number) ]
+
local output = nil
return output or number
+
if not h.isempty(number)
  +
then
  +
number = mw.text.trim(number)
  +
number = string.gsub(number, '^0', '')
  +
output = month_numbers[ string.lower(number) ]
  +
end
  +
  +
return output
 
end
 
end
   
   
  +
--------------------------------------------------------------------------------
 
--takes a date and formats it according to the syntax - https://www.mediawiki.org/wiki/Help:Extension:ParserFunctions##time
 
--takes a date and formats it according to the syntax - https://www.mediawiki.org/wiki/Help:Extension:ParserFunctions##time
 
function p.lua_date_converter(s_date, s_format)
 
function p.lua_date_converter(s_date, s_format)
local s = {} --1 = year, 2 = month, 3 = day
+
local year = nil
local i = 0
+
local month = nil
local j = 0
+
local day = nil
local output = ''
+
local i = 0
+
local j = 0
  +
local output = ''
--'To comma' = 'F j, Y', "dash" = 'm-d-Y'
 
  +
s_format = s_format or 'Ymd'
 
  +
s_format = s_format or 'Ymd'
  +
  +
if h.isempty(s_date) or s_date == 'now'
  +
then output = language:formatDate(s_format)
  +
else
  +
month, day, year = string.match(s_date, '(.+) (.+), (%d%d%d%d)')
  +
if month == nil
  +
then month, day, year = string.match(s_date, '(.+)%-(.+)%-(%d%d%d%d)')
  +
end
  +
if day ~= nil and month ~= nil and year ~= nil
  +
then
  +
month = p.get_month_number({month})
  +
if #day == 1 then day = '0'..day end
  +
if s_format == 'Ymd'
  +
then output = year..month..day
  +
elseif s_format == 'Ym'
  +
then output = year..month
  +
elseif s_format == 'F j, Y'
  +
then
  +
day = string.gsub(day, '^0', '')
  +
month = p.get_month_name({month})
  +
output = month..' '..day..', '..year
  +
else output = language:formatDate(s_format, month..' '..day..' '..year)
  +
end
  +
else output = language:formatDate(s_format, s_date)
  +
end
  +
end
   
  +
return output
if h.isempty(s_date)
 
then output = language:formatDate(s_format)
 
else
 
i = string.find(s_date, '-',1,true)
 
j = string.find(s_date, ', ',1,true)
 
if i ~= nil
 
then
 
j = string.find(s_date, '-',i+1,true)
 
s[2] = p.month({ string.sub(s_date, 1, i-1) })
 
s[3] = string.sub(s_date, i+1, j-1)
 
if #s[3] == 1 then s[3] = '0'..s[3] end
 
s[1] = string.sub(s_date, j+1, #s_date)
 
output = language:formatDate(s_format, s[2]..' '..s[3]..' '..s[1])
 
elseif j ~= nil then
 
s[1] = string.sub(s_date, j+2, #s_date)
 
i = string.find(s_date, ' ',1,true)
 
s[2] = p.month({ string.sub(s_date, 1, i-1) })
 
s[3] = string.sub(s_date, i+1, j-1)
 
if #s[3] == 1 then s[3] = '0'..s[3] end
 
output = language:formatDate(s_format, s[2]..' '..s[3]..' '..s[1])
 
else
 
output = language:formatDate(s_format, s_date)
 
end
 
end
 
return output
 
 
end
 
end
   
  +
  +
--------------------------------------------------------------------------------
 
--compares two dates. Return "true" if 1st date is before the 2nd date, and "false" otherwise.
 
--compares two dates. Return "true" if 1st date is before the 2nd date, and "false" otherwise.
 
function p.lua_date_comparison(date1, date2)
 
function p.lua_date_comparison(date1, date2)
  +
local output
date1 = p.lua_date_converter(date1, 'Ymd')
 
  +
date2 = p.lua_date_converter(date2 or 'now', 'Ymd') --If 2nd date is ommited, then current date is used for comparison.
 
  +
date1 = p.lua_date_converter(date1, 'Ymd')
return date1<=date2
 
  +
if tonumber( string.sub(date1, 1, 4) ) < 2020
  +
and ( h.isempty(date2)
  +
or date2 == 'now'
  +
or tonumber( string.sub(p.lua_date_converter(date2, 'Ymd'), 1, 4) ) >= 2020
  +
)
  +
then output = true
  +
else
  +
date2 = p.lua_date_converter(date2 or 'now', 'Ymd') --If 2nd date is ommited, then current date is used for comparison.
  +
output = date1<=date2
  +
end
  +
  +
return output
 
end
 
end
   
   
  +
--------------------------------------------------------------------------------
 
--returns era based on year
 
--returns era based on year
  +
--[[
function p.getEra(frame)
 
local args = getArgs(frame)
+
function p.get_era(frame)
local year = tonumber(args[1])
+
local args = getArgs(frame)
local key = args[2] or ''
+
local year = tonumber(args[1])
  +
local key = args[2] or ''
local output = ''
 
  +
local output = ''
   
if not h.isempty(year)
+
if not h.isempty(year)
then
+
then
if not h.isempty(key) then key = ' '..key end
+
if not h.isempty(key) then key = ' '..key end
if year<1955 then output = 'Golden-Age'..key end
+
if year<1955 then output = 'Golden-Age'..key end
if year>=1955 and year<1970 then output = 'Silver-Age'..key end
+
if year>=1955 and year<1970 then output = 'Silver-Age'..key end
if year>=1970 and year<1983 then output = 'Bronze-Age'..key end
+
if year>=1970 and year<1983 then output = 'Bronze-Age'..key end
if year>=1983 and year<1992 then output = 'Copper-Age'..key end
+
if year>=1983 and year<1992 then output = 'Copper-Age'..key end
if year>=1992 then output = 'Modern-Age'..key end
+
if year>=1992 then output = 'Modern-Age'..key end
end
+
end
  +
 
return output
+
return output
 
end
 
end
  +
]]--
   
  +
--------------------------------------------------------------------------------
  +
function p.lua_get_publication_category(year, month, day)
  +
local link = ''
  +
local category = ''
  +
local text = ''
   
  +
if not h.isempty(year)
--returns link to date of publication category
 
  +
then
function p.lua_link_to_publication_category(year, month, season)
 
  +
month = p.get_month_name({month})
local output = ''
 
  +
if month ~= nil
 
  +
then
if h.isempty(month) and not h.isempty(season)
 
  +
if h.isempty(day)
then month = season
 
  +
then day = ''
end
 
  +
else day = ' '..day
 
  +
end
if not h.isempty(year)
 
  +
category = year..', '..month
then
 
  +
link = h.LinkToCategory(category, month..day)..', '..h.LinkToCategory(year, year)
if not h.isempty(month)
 
  +
text = month..', '..year
then
 
  +
else
month = p.month({month})
 
  +
category = year
output = '[[:Category:'..year..', '..month..'|'..month..']], [[:Category:'..year..'|'..year..']]'
 
  +
link = h.LinkToCategory(year, year)
else
 
  +
text = year
output = '[[:Category:'..year..'|'..year..']]'
 
  +
end
end
 
end
+
end
  +
 
  +
return link, category, text
return output
 
 
end
 
end
   
   
  +
--------------------------------------------------------------------------------
 
-- returns information about release date
 
-- returns information about release date
 
function p.lua_get_release_date_info(release_date)
 
function p.lua_get_release_date_info(release_date)
local released = true
+
local recent = false
local recent = false
+
local releaseweek
  +
local text = ''
local releaseweek
 
local text = ''
+
local link = ''
local link = ''
+
local year = ''
local category = ''
+
local month = ''
local output = ''
+
local day = ''
  +
local no_day = ''
 
  +
local category = ''
if not h.isempty(release_date)
 
  +
local output = ''
then
 
  +
output = p.lua_date_converter(release_date, 'F j, Y')
 
  +
if not h.isempty(release_date)
released = p.lua_date_comparison(output)
 
  +
then
text = 'Week '..p.lua_date_converter(output, 'W')..', '..p.lua_date_converter(output, 'Y')
 
  +
output = p.lua_date_converter(release_date, 'F j, Y')
link = h.Link(':Category:'..text, output)
 
  +
month, day, year = string.match(output, '(.-) (%d-), (%d%d%d%d)')
recent = p.lua_is_recently_released(output)
 
  +
no_day = month..', '..year
end
 
  +
link = p.lua_get_link_to_release_week(output)
  +
text = h.break_link(link, 1)
  +
recent = p.lua_is_recently_released(output)
  +
end
   
output = {
+
output = {
date = output,
+
date = output,
week = {
+
week = {
text = text,
+
text = text,
link = link
+
link = link
  +
},
},
 
  +
recent = recent,
released = released,
 
  +
day = day,
recent = recent,
 
  +
month = month,
}
 
  +
year = year,
  +
no_day = no_day
  +
}
   
return output
+
return output
 
end
 
end
   
   
  +
--------------------------------------------------------------------------------
 
-- returns information about publication date
 
-- returns information about publication date
function p.lua_get_publication_date_info(year, month, season, canceled)
+
function p.lua_get_publication_date_info(year, month, canceled)
local published = true
+
--local published = true
local recent = false
+
local month_number
local month2
+
local month_name
local categories = {}
+
local categories = {}
local link = ''
+
local link = ''
local text = ''
+
local category = ''
local sortdate = ''
+
local sortdate = ''
local output = ''
+
local output = ''
  +
 
  +
month_number = p.get_month_number({month}) or '01'
if h.isempty(month)
 
  +
month_name = p.get_month_name({month}) or ''
then
 
  +
if not h.isempty(season)
 
  +
if h.isempty(year)
then month = p.month({season})
 
  +
then year = ''
else month = ''
 
  +
end
end
 
  +
else month = p.month({month})
 
  +
if year ~= ''
end
 
  +
then
month2 = m.month({month or '1'})
 
  +
sortdate = year..month_number..'01'
 
  +
--published = p.lua_date_comparison(sortdate)
if not h.isempty(year)
 
  +
sortdate = '&nbsp;'..sortdate
then
 
  +
link, category = p.lua_get_publication_category(year, month_name)
sortdate = p.lua_date_converter(month2..' '..year, 'Ymd')
 
  +
table.insert(categories, year)
published = p.lua_date_comparison(sortdate)
 
  +
table.insert(categories, category)
sortdate = '&nbsp;'..sortdate
 
  +
--table.insert(categories, p.get_era({year}))
if month ~= ''
 
  +
elseif not h.isempty(canceled) and not canceled
then
 
  +
then table.insert(categories, 'Need Comic Dates')
link = year..', '..month
 
  +
end
text = month..', '..year
 
  +
output = {
else
 
  +
link = link,
link = year
 
text = year
+
year = year,
  +
month = month_name,
end
 
  +
sortdate = sortdate,
recent = p.lua_is_recently_published(year, month)
 
  +
--published = published,
table.insert(categories, year)
 
  +
}
table.insert(categories, link)
 
  +
table.insert(categories, p.getEra({year}))
 
  +
return output, categories
link = h.Link(link, text)
 
elseif not h.isempty(canceled) and not canceled
 
then table.insert(categories, 'Need Comic Dates')
 
end
 
output = {
 
link = link,
 
text = text,
 
year = year,
 
month = month,
 
sortdate = sortdate,
 
published = published,
 
recent = recent,
 
}
 
 
return output, categories
 
 
end
 
end
   
  +
-----------------------------------------------------------------------
 
  +
--------------------------------------------------------------------------------
 
--check if comics, episode, movie, etc. was recently released/published
 
--check if comics, episode, movie, etc. was recently released/published
 
function p.isRecent(frame)
 
function p.isRecent(frame)
local args = getArgs(frame)
+
local args = getArgs(frame)
local releasedate = args['releasedate']
+
local release_date = args['releasedate']
local year = args['year']
+
local year = args['year']
local month = args['month']
+
local month = args['month']
local season = args['season']
+
local canceled = args['canceled'] or false
local canceled = args['canceled'] or false
+
local output = false
local output = false
 
   
if not canceled and (p.lua_is_recently_published(year, month) or p.lua_is_recently_released(releasedate))
+
if not canceled and (p.lua_is_recently_published(year, month) or p.lua_is_recently_released(release_date))
then output = true
+
then output = true
end
+
end
  +
 
return output
+
return output
 
end
 
end
   
   
  +
--------------------------------------------------------------------------------
 
function p.lua_is_recently_published(year, month)
 
function p.lua_is_recently_published(year, month)
local current_date = p.lua_date_converter()
+
local current_date = p.lua_date_converter()
local s
+
local s
local publication_date
+
local publication_date
local output = false
+
local output = false
  +
 
if not h.isempty(year)
+
if not h.isempty(year)
then
+
then
month = p.month({month or '1'})
+
month = p.get_month_number({month}) or '01'
publication_date = p.lua_date_converter(month..' 01 '..year, 'Ymd')
+
publication_date = year..month..'01'
s = language:formatDate('Ym', '-2 months')..'01'
+
s = language:formatDate('Ym', '-2 months')..'01'
if publication_date>=s and publication_date<=current_date
+
if publication_date>=s and publication_date<=current_date
then output = true
+
then output = true
  +
end
end
 
end
+
end
   
return output
+
return output
 
end
 
end
   
   
  +
--------------------------------------------------------------------------------
function p.lua_is_recently_released(releasedate)
 
  +
function p.lua_is_recently_released(release_date)
local current_date = p.lua_date_converter()
 
  +
local today = p.lua_date_converter('now', 'Ymd')
local s
 
  +
local output = false
local publication_date
 
  +
local output = false
 
  +
if not h.isempty(release_date)
 
  +
then
if not h.isempty(releasedate)
 
  +
release_date = p.lua_date_converter(release_date, 'Ymd')
then
 
  +
if release_date<=today and
releasedate = p.lua_date_converter(releasedate, 'Ymd')
 
s = language:formatDate('Ymd', '-4 months')
+
release_date>=language:formatDate('Ymd', '-4 months')
  +
then output = true
if releasedate>=s and releasedate<=current_date
 
  +
end
then output = true
 
  +
end
end
 
end
 
   
return output
+
return output
 
end
 
end
   
  +
  +
--------------------------------------------------------------------------------
  +
function p.lua_is_recently_released_episode(year, month, day)
  +
local release_date
  +
local today = p.lua_date_converter('now', 'Ymd')
  +
local output = false
  +
  +
if not h.isempty(year) and not h.isempty(month) and not h.isempty(day)
  +
then
  +
month = p.get_month_number({month})
  +
day = string.rep( '0', 2-#tostring(day) )..day
  +
release_date = year..month..day
  +
if release_date<=today and release_date>=language:formatDate('Ymd', '-2 weeks')
  +
then output = true
  +
end
  +
end
  +
  +
return output
  +
end
  +
  +
--*************************************************************************************************
  +
-- functions to manually calculate number of week (based on date) or date (based on number of week)
  +
  +
--------------------------------------------------------------------------------
  +
-- return week number and year from "Week WW, YYYY" format
  +
function p.lua_get_week_number_and_year_from_week_name(week_name)
  +
local week_number
  +
local year
  +
  +
week_number, year = string.match(week_name, 'Week (%d+), (%d%d%d%d)')
  +
  +
return tonumber(week_number), tonumber(year)
  +
end
  +
  +
  +
--------------------------------------------------------------------------------
  +
function p.lua_get_week_name_from_week_number_and_year(week_number, year)
  +
local output = ''
  +
  +
if not h.isempty(week_number) and not h.isempty(year)
  +
then
  +
if #tostring(week_number) == 1
  +
then week_number = '0'..week_number
  +
end
  +
output = 'Week '..week_number..', '..year
  +
end
  +
  +
return output
  +
end
  +
  +
  +
--------------------------------------------------------------------------------
  +
function p.lua_is_leap_year(year)
  +
local output = false
  +
if math.fmod( year-1904, 4 ) == 0
  +
then output = true
  +
end
  +
  +
return output
  +
end
  +
  +
  +
--------------------------------------------------------------------------------
  +
function p.lua_get_day_of_year(year, month, day)
  +
local output = day
  +
  +
for i = 1, month-1 do
  +
output = output + days_in_month[i]
  +
end
  +
  +
if p.lua_is_leap_year(year) and month > 2
  +
then output = output + 1
  +
end
  +
  +
return output
  +
end
  +
  +
  +
--------------------------------------------------------------------------------
  +
function p.lua_get_date_from_day_of_year(day_of_year, year)
  +
local i = 1
  +
local j
  +
local leap_year = p.lua_is_leap_year(year)
  +
local output
  +
  +
if day_of_year > 366 and leap_year
  +
then
  +
day_of_year = day_of_year - 366
  +
year = year + 1
  +
elseif day_of_year > 365 and not leap_year
  +
then
  +
day_of_year = day_of_year - 365
  +
year = year + 1
  +
elseif day_of_year < 0
  +
then
  +
year = year - 1
  +
leap_year = p.lua_is_leap_year(year)
  +
if leap_year
  +
then day_of_year = day_of_year + 366
  +
else day_of_year = day_of_year + 365
  +
end
  +
end
  +
  +
if day_of_year == 0
  +
then output = 'December 31, '..year-1
  +
else
  +
output = day_of_year
  +
j = days_in_month[1]
  +
  +
while output > j do
  +
output = output - j
  +
i = i + 1
  +
if i == 2 and leap_year
  +
then j = 29
  +
else j = days_in_month[i]
  +
end
  +
end
  +
  +
output = p.get_month_name({i})..' '..output..', '..year
  +
end
  +
  +
return output
  +
end
  +
  +
  +
--------------------------------------------------------------------------------
  +
-- return day of week for January 1 (1 = Monday, 7 = Sunday, etc.)
  +
-- day of week repeats every 28 years
  +
function p.lua_get_day_of_week_of_january_1(year)
  +
local output = {5,7,1,2,3,5,6,7,1,3,4,5,6,1,2,3,4,6,7,1,2,4,5,6,7,2,3,4}
  +
local year_number = math.fmod( year-1904, 28 ) + 1
  +
return output[year_number]
  +
end
  +
  +
  +
--------------------------------------------------------------------------------
  +
-- return first day of the year's first week. If it started in december of the previous year, then negative number is returned (for example, first week of 2020 year started on December 30, 2019, so function returns -2)
  +
function p.lua_get_first_day_of_first_week_of_year(year)
  +
local first_day = p.lua_get_day_of_week_of_january_1(year)
  +
return math.fmod( 11-first_day, 7) - 3
  +
end
  +
  +
  +
--------------------------------------------------------------------------------
  +
function p.lua_get_day_of_week(year, month, day)
  +
local first_day = p.lua_get_day_of_week_of_january_1(year)
  +
local day_of_year = p.lua_get_day_of_year(year, month, day)
  +
local output
  +
  +
output = math.fmod(first_day + day_of_year - 1, 7 )
  +
if output == 0
  +
then output = 7
  +
end
  +
  +
return output
  +
end
  +
  +
  +
--------------------------------------------------------------------------------
  +
function p.lua_get_week_number(year, month, day)
  +
local day_of_year = p.lua_get_day_of_year(year, month, day)
  +
local day_of_week = p.lua_get_day_of_week(year, month, day)
  +
local week_number = math.floor( (day_of_year - day_of_week + 10) / 7 )
  +
local output
  +
  +
if week_number == 0
  +
then
  +
year = year - 1
  +
week_number = p.lua_get_last_week_of_year2(year)
  +
elseif week_number == 53 and p.lua_get_last_week_of_year2(year) == 52
  +
then
  +
year = year + 1
  +
week_number = 1
  +
end
  +
  +
output = p.lua_get_week_name_from_week_number_and_year(week_number, year)
  +
  +
return output
  +
end
  +
  +
  +
--------------------------------------------------------------------------------
  +
-- return date of Wednesday for "year"'s week
  +
function p.lua_get_date_from_week_number(week_number, year)
  +
local first_day_of_first_week
  +
local i = 1
  +
local leap_year
  +
local first_day
  +
local last_week = p.lua_get_last_week_of_year2(year)
  +
local month
  +
local output
  +
  +
if week_number > last_week
  +
then
  +
week_number = week_number - last_week
  +
year = year + 1
  +
end
  +
  +
first_day_of_first_week = p.lua_get_first_day_of_first_week_of_year(year)
  +
leap_year = p.lua_is_leap_year(year)
  +
first_day = p.lua_get_day_of_week_of_january_1(year)
  +
  +
output = first_day_of_first_week + 7 * (week_number-1) + 3
  +
output = p.lua_get_date_from_day_of_year(output, year)
  +
  +
return output
  +
end
  +
  +
  +
--------------------------------------------------------------------------------
  +
function p.lua_get_last_week_of_year(year)
  +
local function week_number(y)
  +
local output = y + (y / 4) - (y / 100) + (y / 400)
  +
return math.floor( math.fmod(output, 7) )
  +
end
  +
  +
if week_number(year) == 4 or week_number(year - 1) == 3
  +
then return 53
  +
else return 52
  +
end
  +
end
  +
  +
  +
--------------------------------------------------------------------------------
  +
function p.lua_get_last_week_of_year2(year)
  +
local first_day = p.lua_get_day_of_week_of_january_1(year)
  +
local last_day = p.lua_get_day_of_week(year, 12, 31)
  +
local leap_year = p.lua_is_leap_year(year)
  +
  +
if ( not leap_year and (first_day == 4 or last_day == 4) ) or ( leap_year and (first_day == 3 or last_day == 5) )
  +
then return 53
  +
else return 52
  +
end
  +
end
  +
--*************************************************************************************************
  +
  +
--------------------------------------------------------------------------------
  +
function p.lua_get_previous_next_weeks(week_number, year)
  +
local previous_week
  +
local next_week
  +
  +
if week_number == 1
  +
then previous_week = p.lua_get_date_from_week_number(p.lua_get_last_week_of_year2(year - 1), year - 1)
  +
else previous_week = p.lua_get_date_from_week_number(week_number - 1, year)
  +
end
  +
  +
if week_number == p.lua_get_last_week_of_year2(year)
  +
then next_week = p.lua_get_date_from_week_number(1, year + 1)
  +
else next_week = p.lua_get_date_from_week_number(week_number + 1, year)
  +
end
  +
  +
return previous_week, next_week
  +
end
  +
  +
  +
--------------------------------------------------------------------------------
  +
function p.get_previous_next_weeks(frame)
  +
local design = require("Module:Design")
  +
local current_date = p.lua_get_release_week_from_release_date( p.lua_date_converter() )
  +
local pagename = mw.title.getCurrentTitle().text
  +
local link
  +
local category = true
  +
local previous_week
  +
local next_week
  +
local output = ''
  +
  +
week_number, year = p.lua_get_week_number_and_year_from_week_name(pagename)
  +
if week_number == nil or year == nil
  +
then
  +
week_number, year = p.lua_get_week_number_and_year_from_week_name(current_date)
  +
category = false
  +
end
  +
  +
previous_week, next_week = p.lua_get_previous_next_weeks(week_number, year)
  +
  +
link = p.lua_get_release_week_from_release_date(previous_week)
  +
previous_week = h.LinkToCategory(link, previous_week)
  +
  +
link = p.lua_get_release_week_from_release_date(next_week)
  +
next_week = h.LinkToCategory(link, next_week)
  +
  +
pagename = p.lua_get_date_from_week_number(week_number, year)
  +
  +
output = design.messagebox({ previous_week..' &mdash; '..pagename..' &mdash; '..next_week })
  +
  +
if category
  +
then
  +
category = p.lua_get_date_from_week_number(week_number, year)
  +
category = string.gsub(category, ' %d+, ', ', ')
  +
category = 'Comics Released in '..category
  +
output = output..h.Category(category)
  +
end
  +
  +
return output
  +
end
  +
  +
  +
--------------------------------------------------------------------------------
  +
function p.lua_get_release_week_from_release_date(release_date)
  +
local year
  +
local month
  +
local day
  +
local output = ''
  +
  +
if not h.isempty(release_date)
  +
then
  +
release_date = p.lua_date_converter(release_date, 'F j, Y')
  +
month, day, year = string.match(release_date, '(.-) (%d-), (%d%d%d%d)')
  +
month = tonumber( p.get_month_number({month}) )
  +
output = p.lua_get_week_number(year, month, day)
  +
end
  +
  +
return output
  +
end
  +
  +
  +
--------------------------------------------------------------------------------
  +
-- used in Template:ReleaseWeek
  +
function p.get_release_week_from_release_date(frame)
  +
local args = getArgs(frame)
  +
local release_date = args[1]
  +
local output
  +
  +
if h.isempty(release_date)
  +
then output = p.lua_get_release_week_from_release_date( p.lua_date_converter() ) -- current date
  +
else output = p.lua_get_release_week_from_release_date(release_date)
  +
end
  +
  +
return output
  +
end
  +
  +
  +
--------------------------------------------------------------------------------
  +
function p.lua_get_link_to_release_week(release_date, week_number, year)
  +
local month
  +
local day
  +
local output = ''
  +
  +
if not h.isempty(release_date)
  +
then
  +
release_date = p.lua_date_converter(release_date, 'F j, Y')
  +
week_number = p.lua_get_release_week_from_release_date(release_date)
  +
output = h.LinkToCategory(week_number, release_date)
  +
elseif not h.isempty(week_number) and not h.isempty(year)
  +
then
  +
release_date = p.lua_get_date_from_week_number(week_number, year)
  +
week_number = p.lua_get_week_name_from_week_number_and_year(week_number, year)
  +
output = h.LinkToCategory(week_number, release_date)
  +
end
  +
  +
return output
  +
end
  +
  +
  +
--------------------------------------------------------------------------------
  +
function p.lua_get_release_week_category(release_date)
  +
local week
  +
local output = ''
  +
  +
week = p.lua_get_release_week_from_release_date(release_date)
  +
if week ~= ''
  +
then output = h.Category(week)
  +
end
  +
  +
return output
  +
end
  +
  +
  +
--------------------------------------------------------------------------------
  +
-- used in Template:Month Category
  +
function p.get_previous_and_next_month(frame)
  +
local pagename = mw.title.getCurrentTitle().text
  +
local year
  +
local month
  +
local month_number
  +
local next_month
  +
local previous_month
  +
local design = require("Module:Design")
  +
local output = ''
  +
  +
year, month = string.match(pagename, '(%d+), (.+)')
  +
if year ~= nil and month ~= nil
  +
then
  +
year = tonumber(year)
  +
month_number = tonumber( p.get_month_number({month}) )
  +
if month_number == 1
  +
then
  +
previous_month = tostring(year - 1)..', December'
  +
next_month = tostring(year)..', February'
  +
elseif month_number == 12
  +
then
  +
previous_month = tostring(year)..', November'
  +
next_month = tostring(year+1)..', January'
  +
else
  +
previous_month = tostring(year)..', '..p.get_month_name({month_number-1})
  +
next_month = tostring(year)..', '..p.get_month_name({month_number+1})
  +
end
  +
  +
previous_month = h.LinkToCategory(previous_month, previous_month)
  +
next_month = h.LinkToCategory(next_month, next_month)
  +
  +
output = design.messagebox({previous_month..' — '..pagename..' — '..next_month})
  +
output = output..h.Category(year, year..' '..p.get_month_number({month}))
  +
end
  +
  +
return output
  +
end
   
 
return p
 
return p

Revision as of 06:42, 28 August 2021

Documentation for this module may be created at Module:Date/doc

local p = {}
local monthData = mw.loadData( 'Module:Month/data' )
local h = require("Module:HF")
local getArgs = require('Dev:Arguments').getArgs
local language = mw.language.new('en')
local month_names = monthData[1]
local month_numbers = monthData[2]
local days_in_month = {31,28,31,30,31,30,31,31,30,31,30,31}

--------------------------------------------------------------------------------
-- return full month name
function p.get_month_name(frame)
	local args = getArgs(frame)
	local name = args[1]
	local output = nil
	
	if not h.isempty(name)
		then
			name = mw.text.trim(name)
			name = string.gsub(name, '^0', '')
			output = month_names[ string.lower(name) ]
	end

	return output
end


--------------------------------------------------------------------------------
-- return month number
function p.get_month_number(frame)
	local args = getArgs(frame)
	local number = args[1]
	local output = nil
	if not h.isempty(number)
		then
			number = mw.text.trim(number)
			number = string.gsub(number, '^0', '')
			output = month_numbers[ string.lower(number) ]
	end

	return output
end


--------------------------------------------------------------------------------
--takes a date and formats it according to the syntax - https://www.mediawiki.org/wiki/Help:Extension:ParserFunctions##time
function p.lua_date_converter(s_date, s_format)
	local year = nil
	local month = nil
	local day = nil
	local i = 0
	local j = 0
	local output = ''
	
	s_format = s_format or 'Ymd'
	
	if h.isempty(s_date) or s_date == 'now'
		then output = language:formatDate(s_format)
		else
			month, day, year = string.match(s_date, '(.+) (.+), (%d%d%d%d)')
			if month == nil
				then month, day, year = string.match(s_date, '(.+)%-(.+)%-(%d%d%d%d)')
			end
			if day ~= nil and month ~= nil and year ~= nil
				then
					month = p.get_month_number({month})
					if #day == 1 then day = '0'..day end
					if s_format == 'Ymd'
						then output = year..month..day
						elseif s_format == 'Ym'
							 then output = year..month
						elseif s_format == 'F j, Y'
							then
								day = string.gsub(day, '^0', '')
								month = p.get_month_name({month})
								output = month..' '..day..', '..year
						else output = language:formatDate(s_format, month..' '..day..' '..year)
					end
				else output = language:formatDate(s_format, s_date)
			end
	end

	return output
end


--------------------------------------------------------------------------------
--compares two dates. Return "true" if 1st date is before the 2nd date, and "false" otherwise.
function p.lua_date_comparison(date1, date2)
	local output
	
	date1 = p.lua_date_converter(date1, 'Ymd')
	if tonumber( string.sub(date1, 1, 4) ) < 2020 
		and (   h.isempty(date2) 
				or date2 == 'now' 
				or tonumber( string.sub(p.lua_date_converter(date2, 'Ymd'), 1, 4) ) >= 2020
			)
		then output = true
		else
			date2 = p.lua_date_converter(date2 or 'now', 'Ymd') --If 2nd date is ommited, then current date is used for comparison.
			output = date1<=date2
	end
	
	return output
end


--------------------------------------------------------------------------------
--returns era based on year
--[[
function p.get_era(frame)
	local args = getArgs(frame)
	local year = tonumber(args[1])
	local key = args[2] or ''
	local output = ''

	if not h.isempty(year)
		then
			if not h.isempty(key) then key = ' '..key end
			if year<1955 then output = 'Golden-Age'..key end
			if year>=1955 and year<1970 then output = 'Silver-Age'..key end
			if year>=1970 and year<1983 then output = 'Bronze-Age'..key end
			if year>=1983 and year<1992 then output = 'Copper-Age'..key end
			if year>=1992 then output = 'Modern-Age'..key end
	end
	
	return output
end
]]--

--------------------------------------------------------------------------------
function p.lua_get_publication_category(year, month, day)
	local link = ''
	local category = ''
	local text = ''

	if not h.isempty(year)
		then
			month = p.get_month_name({month})
			if month ~= nil
				then 
					if h.isempty(day)
						then day = ''
						else day = ' '..day
					end
					category = year..', '..month
					link = h.LinkToCategory(category, month..day)..', '..h.LinkToCategory(year, year)
					text = month..', '..year
				else
					category = year
					link = h.LinkToCategory(year, year)
					text = year
			end
	end
	
	return link, category, text
end


--------------------------------------------------------------------------------
-- returns information about release date
function p.lua_get_release_date_info(release_date)
	local recent = false
	local releaseweek
	local text = ''
	local link = ''
	local year = ''
	local month = ''
	local day = ''
	local no_day = ''
	local category = ''
	local output = ''
	
	if not h.isempty(release_date)
		then 
			output = p.lua_date_converter(release_date, 'F j, Y')
			month, day, year = string.match(output, '(.-) (%d-), (%d%d%d%d)')
			no_day = month..', '..year
			link = p.lua_get_link_to_release_week(output)
			text = h.break_link(link, 1)
			recent = p.lua_is_recently_released(output)
	end

	output = {
		date = output, 
		week = {
			text = text, 
			link = link
		},
		recent = recent,
		day = day,
		month = month,
		year = year,
		no_day = no_day
	}

	return output
end


--------------------------------------------------------------------------------
-- returns information about publication date
function p.lua_get_publication_date_info(year, month, canceled)
	--local published = true
	local month_number
	local month_name
	local categories = {}
	local link = ''
	local category = ''
	local sortdate = ''
	local output = ''
	
	month_number = p.get_month_number({month}) or '01'
	month_name = p.get_month_name({month}) or ''

	if h.isempty(year)
		then year = ''
	end
	
	if year ~= ''
		then
			sortdate = year..month_number..'01'
			--published = p.lua_date_comparison(sortdate)
			sortdate = '&nbsp;'..sortdate
			link, category = p.lua_get_publication_category(year, month_name)
			table.insert(categories, year)
			table.insert(categories, category)
			--table.insert(categories, p.get_era({year}))
		elseif not h.isempty(canceled) and not canceled
			then table.insert(categories, 'Need Comic Dates')
	end
	output = {
		link = link, 
		year = year, 
		month = month_name, 
		sortdate = sortdate,
		--published = published,
	}
	
	return output, categories
end


--------------------------------------------------------------------------------
--check if comics, episode, movie, etc. was recently released/published
function p.isRecent(frame)
	local args = getArgs(frame)
	local release_date = args['releasedate']
	local year = args['year']
	local month = args['month']
	local canceled = args['canceled'] or false
	local output = false

	if not canceled and (p.lua_is_recently_published(year, month) or p.lua_is_recently_released(release_date))
		then output = true
	end
	
	return output
end


--------------------------------------------------------------------------------
function p.lua_is_recently_published(year, month)
	local current_date = p.lua_date_converter()
	local s
	local publication_date
	local output = false
	
	if not h.isempty(year)
		then
			month = p.get_month_number({month}) or '01'
			publication_date = year..month..'01'
			s = language:formatDate('Ym', '-2 months')..'01'
			if publication_date>=s and publication_date<=current_date
				then output = true
			end
	end

	return output
end


--------------------------------------------------------------------------------
function p.lua_is_recently_released(release_date)
	local today = p.lua_date_converter('now', 'Ymd')
	local output = false
	
	if not h.isempty(release_date)
		then
			release_date = p.lua_date_converter(release_date, 'Ymd')
			if release_date<=today and 
			   release_date>=language:formatDate('Ymd', '-4 months') 
				then output = true
			end
	end

	return output
end


--------------------------------------------------------------------------------
function p.lua_is_recently_released_episode(year, month, day)
	local release_date
	local today = p.lua_date_converter('now', 'Ymd')
	local output = false
	
	if not h.isempty(year) and not h.isempty(month) and not h.isempty(day)
		then
			month = p.get_month_number({month})
			day = string.rep( '0', 2-#tostring(day) )..day
			release_date = year..month..day
			if release_date<=today and release_date>=language:formatDate('Ymd', '-2 weeks') 
				then output = true
			end
	end

	return output
end

--*************************************************************************************************
-- functions to manually calculate number of week (based on date) or date (based on number of week)

--------------------------------------------------------------------------------
-- return week number and year from "Week WW, YYYY" format
function p.lua_get_week_number_and_year_from_week_name(week_name)
	local week_number
	local year
	
	week_number, year = string.match(week_name, 'Week (%d+), (%d%d%d%d)')
	
	return tonumber(week_number), tonumber(year)
end


--------------------------------------------------------------------------------
function p.lua_get_week_name_from_week_number_and_year(week_number, year)
	local output = ''
	
	if not h.isempty(week_number) and not h.isempty(year)
		then 
			if #tostring(week_number) == 1
				then week_number = '0'..week_number
			end
			output = 'Week '..week_number..', '..year
	end
	
	return output
end


--------------------------------------------------------------------------------
function p.lua_is_leap_year(year)
	local output = false
	if math.fmod( year-1904, 4 ) == 0
		then output = true
	end
	
	return output
end


--------------------------------------------------------------------------------
function p.lua_get_day_of_year(year, month, day)
	local output = day

	for i = 1, month-1 do
		output = output + days_in_month[i]
	end

	if p.lua_is_leap_year(year) and month > 2
		then output = output + 1
	end

	return output
end


--------------------------------------------------------------------------------
function p.lua_get_date_from_day_of_year(day_of_year, year)
	local i = 1
	local j
	local leap_year = p.lua_is_leap_year(year)
	local output

	if day_of_year > 366 and leap_year
		then 
			day_of_year = day_of_year - 366
			year = year + 1
		elseif day_of_year > 365 and not leap_year
			then
				day_of_year = day_of_year - 365
				year = year + 1
		elseif day_of_year < 0
			then
				year = year - 1
				leap_year = p.lua_is_leap_year(year)
				if leap_year
					then day_of_year = day_of_year + 366
					else day_of_year = day_of_year + 365
				end
	end
	
	if day_of_year == 0
		then output = 'December 31, '..year-1
		else 
			output = day_of_year
			j = days_in_month[1]

			while output > j do
				output = output - j
				i = i + 1
				if i == 2 and leap_year
					then j = 29
					else j = days_in_month[i]
				end
			end

			output = p.get_month_name({i})..' '..output..', '..year
	end
	
	return output
end


--------------------------------------------------------------------------------
-- return day of week for January 1 (1 = Monday, 7 = Sunday, etc.)
-- day of week repeats every 28 years
function p.lua_get_day_of_week_of_january_1(year)
	local output = {5,7,1,2,3,5,6,7,1,3,4,5,6,1,2,3,4,6,7,1,2,4,5,6,7,2,3,4}
	local year_number = math.fmod( year-1904, 28 ) + 1
	return output[year_number]
end   


--------------------------------------------------------------------------------
-- return first day of the year's first week. If it started in december of the previous year, then negative number is returned (for example, first week of 2020 year started on December 30, 2019, so function returns -2)
function p.lua_get_first_day_of_first_week_of_year(year)
	local first_day = p.lua_get_day_of_week_of_january_1(year)
	return math.fmod( 11-first_day, 7) - 3
end


--------------------------------------------------------------------------------
function p.lua_get_day_of_week(year, month, day)
	local first_day = p.lua_get_day_of_week_of_january_1(year)
	local day_of_year = p.lua_get_day_of_year(year, month, day)
	local output

	output = math.fmod(first_day + day_of_year - 1, 7 )
	if output == 0
		then output = 7
	end
	
	return output
end


--------------------------------------------------------------------------------
function p.lua_get_week_number(year, month, day)
	local day_of_year = p.lua_get_day_of_year(year, month, day)
	local day_of_week = p.lua_get_day_of_week(year, month, day)
	local week_number = math.floor( (day_of_year - day_of_week + 10) / 7 )
	local output

	if week_number == 0
		then 
			year = year - 1
			week_number = p.lua_get_last_week_of_year2(year)
		elseif week_number == 53 and p.lua_get_last_week_of_year2(year) == 52
			then 
				year = year + 1
				week_number = 1
	end
	
	output = p.lua_get_week_name_from_week_number_and_year(week_number, year)
	
	return output
end


--------------------------------------------------------------------------------
-- return date of Wednesday for "year"'s week
function p.lua_get_date_from_week_number(week_number, year)
	local first_day_of_first_week
	local i = 1
	local leap_year
	local first_day
	local last_week = p.lua_get_last_week_of_year2(year)
	local month
	local output

	if week_number > last_week
		then
			week_number = week_number - last_week
			year = year + 1
	end
	
	first_day_of_first_week = p.lua_get_first_day_of_first_week_of_year(year)
	leap_year = p.lua_is_leap_year(year)
	first_day = p.lua_get_day_of_week_of_january_1(year)

	output = first_day_of_first_week + 7 * (week_number-1) + 3
	output = p.lua_get_date_from_day_of_year(output, year)

	return output
end


--------------------------------------------------------------------------------
function p.lua_get_last_week_of_year(year)
	local function week_number(y)
		local output = y + (y / 4) - (y / 100) + (y / 400)
		return math.floor( math.fmod(output, 7) )
	end

	if week_number(year) == 4 or week_number(year - 1) == 3
		then return 53
		else return 52
	end
end


--------------------------------------------------------------------------------
function p.lua_get_last_week_of_year2(year)
	local first_day = p.lua_get_day_of_week_of_january_1(year)
	local last_day = p.lua_get_day_of_week(year, 12, 31)
	local leap_year = p.lua_is_leap_year(year)
	
	if ( not leap_year and (first_day == 4 or last_day == 4) ) or ( leap_year and (first_day == 3 or last_day == 5) )
		then return 53
		else return 52
	end
end
--*************************************************************************************************

--------------------------------------------------------------------------------
function p.lua_get_previous_next_weeks(week_number, year)
	local previous_week
	local next_week

	if week_number == 1
		then previous_week = p.lua_get_date_from_week_number(p.lua_get_last_week_of_year2(year - 1), year - 1)
		else previous_week = p.lua_get_date_from_week_number(week_number - 1, year)
	end

	if week_number == p.lua_get_last_week_of_year2(year)
		then next_week = p.lua_get_date_from_week_number(1, year + 1)
		else next_week = p.lua_get_date_from_week_number(week_number + 1, year)
	end

	return previous_week, next_week
end


--------------------------------------------------------------------------------
function p.get_previous_next_weeks(frame)
	local design = require("Module:Design")
	local current_date = p.lua_get_release_week_from_release_date( p.lua_date_converter() ) 
	local pagename = mw.title.getCurrentTitle().text
	local link
	local category = true
	local previous_week
	local next_week
	local output = ''
	
	week_number, year = p.lua_get_week_number_and_year_from_week_name(pagename)
	if week_number == nil or year == nil
		then
			week_number, year = p.lua_get_week_number_and_year_from_week_name(current_date)
			category = false
	end
			
	previous_week, next_week = p.lua_get_previous_next_weeks(week_number, year)
			
	link = p.lua_get_release_week_from_release_date(previous_week)
	previous_week = h.LinkToCategory(link, previous_week)

	link = p.lua_get_release_week_from_release_date(next_week)
	next_week = h.LinkToCategory(link, next_week)
			
	pagename = p.lua_get_date_from_week_number(week_number, year)

	output = design.messagebox({ previous_week..'  &mdash;  '..pagename..'  &mdash;  '..next_week })
			
	if category
		then
			category = p.lua_get_date_from_week_number(week_number, year)
			category = string.gsub(category, ' %d+, ', ', ')
			category = 'Comics Released in '..category
			output = output..h.Category(category)
	end
	
	return output
end


--------------------------------------------------------------------------------
function p.lua_get_release_week_from_release_date(release_date)
	local year
	local month
	local day
	local output = ''

	if not h.isempty(release_date)
		then
			release_date = p.lua_date_converter(release_date, 'F j, Y')
			month, day, year = string.match(release_date, '(.-) (%d-), (%d%d%d%d)')
			month = tonumber( p.get_month_number({month}) )
			output = p.lua_get_week_number(year, month, day)
	end
	
	return output
end	


--------------------------------------------------------------------------------
-- used in Template:ReleaseWeek
function p.get_release_week_from_release_date(frame)
	local args = getArgs(frame)
	local release_date = args[1]
	local output
	
	if h.isempty(release_date)
		then output = p.lua_get_release_week_from_release_date( p.lua_date_converter() )  -- current date
		else output = p.lua_get_release_week_from_release_date(release_date)
	end
	
	return output
end
	

--------------------------------------------------------------------------------
function p.lua_get_link_to_release_week(release_date, week_number, year)
	local month
	local day
	local output = ''
	
	if not h.isempty(release_date)
		then
			release_date = p.lua_date_converter(release_date, 'F j, Y')
			week_number = p.lua_get_release_week_from_release_date(release_date)
			output = h.LinkToCategory(week_number, release_date)
		elseif not h.isempty(week_number) and not h.isempty(year)
			then
				release_date = p.lua_get_date_from_week_number(week_number, year)
				week_number = p.lua_get_week_name_from_week_number_and_year(week_number, year)
				output = h.LinkToCategory(week_number, release_date)
	end
	
	return output
end


--------------------------------------------------------------------------------
function p.lua_get_release_week_category(release_date)
	local week
	local output = ''
	
	week = p.lua_get_release_week_from_release_date(release_date)
	if week ~= ''
		then output = h.Category(week)
	end
	
	return output
end


--------------------------------------------------------------------------------
-- used in Template:Month Category
function p.get_previous_and_next_month(frame)
	local pagename = mw.title.getCurrentTitle().text
	local year
	local month
	local month_number
	local next_month
	local previous_month
	local design = require("Module:Design")
	local output = ''
	
	year, month = string.match(pagename, '(%d+), (.+)')
	if year ~= nil and month ~= nil
		then
			year = tonumber(year)
			month_number = tonumber( p.get_month_number({month}) )
			if month_number == 1
				then
					previous_month = tostring(year - 1)..', December'
					next_month = tostring(year)..', February'
				elseif month_number == 12
					then
						previous_month = tostring(year)..', November'
						next_month = tostring(year+1)..', January'
				else
					previous_month = tostring(year)..', '..p.get_month_name({month_number-1})
					next_month = tostring(year)..', '..p.get_month_name({month_number+1})
			end
	
			previous_month = h.LinkToCategory(previous_month, previous_month)
			next_month = h.LinkToCategory(next_month, next_month)
	
			output = design.messagebox({previous_month..' — '..pagename..' — '..next_month})
			output = output..h.Category(year, year..' '..p.get_month_number({month}))
	end
	
	return output
end

return p