Marvel Database
Register
Advertisement

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}

--------------------------------------------------------------------------------
function p.get_current_year()
	return tonumber(language:formatDate('Y'))
end

--------------------------------------------------------------------------------
-- 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 current_year = p.get_current_year()
	local output
	
	date1 = p.lua_date_converter(date1, 'Ymd')
	if tonumber( string.sub(date1, 1, 4) ) < current_year 
		and (   h.isempty(date2) 
				or date2 == 'now' 
				or tonumber( string.sub(p.lua_date_converter(date2, 'Ymd'), 1, 4) ) >= current_year
			)
		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, page_type)
	local link = ''
	local category = ''
	local text = ''
	
	if h.isempty(page_type)
		then page_type = ''
	end

	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..page_type
					link = h.LinkToCategory(category, month..day)..', '..h.LinkToCategory(year..page_type, year)
					text = month..day..', '..year
				else
					category = year..page_type
					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, page_type)
	local function get_sortdate(year, month)
		local month_number = p.get_month_number({month}) or '01'
		local output = year
		
		if output == ''
			then output = '9999'
		end
		
		return output..'-'..month_number
	end
	local month_name = p.get_month_name({month}) or ''
	local categories = {}
	local link = ''
	local category = ''
	local output = ''
	
	if not h.isempty(page_type) and page_type == 'Comic'
		then page_type = ' Cover Date'
		else page_type = ''
	end

	if h.isempty(year)
		then year = ''
	end
	
	if year ~= ''
		then
			link, category = p.lua_get_publication_category(year, month_name, nil, page_type)
			table.insert(categories, year..page_type)
			table.insert(categories, category)
		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 = get_sortdate(year, month),
	}
	
	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', '-1 month') 
				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', '-1 month') 
				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 = previous_week..'  &mdash;  '..pagename..'  &mdash;  '..next_week
	output = output .. '<br>' .. tostring(mw.html.create('span'):addClass('messagebox__help'):wikitext('See Also: ' .. h.LinkToCategory('Active Volumes', 'list of currently active series')))
	output = design.messagebox({ output })
			
	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


return p
Advertisement