<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en-GB">
	<id>https://stockhub.co/index.php?action=history&amp;feed=atom&amp;title=Module%3ASandbox%2FRexxS%2FCalcDate</id>
	<title>Module:Sandbox/RexxS/CalcDate - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://stockhub.co/index.php?action=history&amp;feed=atom&amp;title=Module%3ASandbox%2FRexxS%2FCalcDate"/>
	<link rel="alternate" type="text/html" href="https://stockhub.co/index.php?title=Module:Sandbox/RexxS/CalcDate&amp;action=history"/>
	<updated>2026-05-24T03:22:32Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.43.5</generator>
	<entry>
		<id>https://stockhub.co/index.php?title=Module:Sandbox/RexxS/CalcDate&amp;diff=146064&amp;oldid=prev</id>
		<title>imported&gt;Legoktm: Replace Module:No globals with require( &quot;strict&quot; )</title>
		<link rel="alternate" type="text/html" href="https://stockhub.co/index.php?title=Module:Sandbox/RexxS/CalcDate&amp;diff=146064&amp;oldid=prev"/>
		<updated>2022-10-23T21:09:07Z</updated>

		<summary type="html">&lt;p&gt;Replace &lt;a href=&quot;/research/Module:No_globals&quot; title=&quot;Module:No globals&quot;&gt;Module:No globals&lt;/a&gt; with require( &amp;quot;strict&amp;quot; )&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;--[[ CalcDate&lt;br /&gt;
Modified from chunks of Module:Time&lt;br /&gt;
Main function: getYearMonthDay&lt;br /&gt;
takes a date string like &amp;quot;second Friday in June&amp;quot; as parameter |date=&lt;br /&gt;
and a year as parameter |year= (uses current year if omitted)&lt;br /&gt;
and returns the date in YYYY-MM-DD format, e.g. 2018-06-08&lt;br /&gt;
Other formats are possible.&lt;br /&gt;
]]&lt;br /&gt;
&lt;br /&gt;
require (&amp;#039;strict&amp;#039;)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--[[ is_set(var)&lt;br /&gt;
Whether variable is set or not.  A variable is set when it is not nil and not empty.&lt;br /&gt;
]]&lt;br /&gt;
local function is_set(var)&lt;br /&gt;
	return var and var ~= &amp;#039;&amp;#039;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[ current_year()&lt;br /&gt;
returns the current year&lt;br /&gt;
]]&lt;br /&gt;
local function current_year()&lt;br /&gt;
	return os.date(&amp;#039;%Y&amp;#039;, os.time())&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--[[ decode_date_event(date_event_string)&lt;br /&gt;
extract ordinal, day-name, and month from daylight saving start/end definition string as digits:&lt;br /&gt;
	Second Sunday in March&lt;br /&gt;
returns&lt;br /&gt;
	2 0 3&lt;br /&gt;
Case doesn&amp;#039;t matter but the form of the string does:&lt;br /&gt;
	&amp;lt;ordinal&amp;gt; &amp;lt;day&amp;gt; &amp;lt;any single word&amp;gt; &amp;lt;month&amp;gt; – all are separated by spaces&lt;br /&gt;
]]&lt;br /&gt;
local function decode_date_event(date_event_string)&lt;br /&gt;
	local ordinals = {&lt;br /&gt;
		[&amp;#039;1st&amp;#039;] = 1, [&amp;#039;first&amp;#039;] = 1, [&amp;#039;2nd&amp;#039;] = 2, [&amp;#039;second&amp;#039;] = 2, [&amp;#039;3rd&amp;#039;] = 3, [&amp;#039;third&amp;#039;] = 3,&lt;br /&gt;
		[&amp;#039;4th&amp;#039;] = 4, [&amp;#039;fourth&amp;#039;] = 4, [&amp;#039;5th&amp;#039;] = 5, [&amp;#039;fifth&amp;#039;] = 5, [&amp;#039;last&amp;#039;] = -1&lt;br /&gt;
	}&lt;br /&gt;
	local days = {&lt;br /&gt;
		[&amp;#039;sunday&amp;#039;] = 0, [&amp;#039;monday&amp;#039;] = 1, [&amp;#039;tuesday&amp;#039;] = 2, [&amp;#039;wednesday&amp;#039;] = 3, [&amp;#039;thursday&amp;#039;] = 4, [&amp;#039;friday&amp;#039;] = 5, [&amp;#039;saturday&amp;#039;] = 6&lt;br /&gt;
	}&lt;br /&gt;
	local months = {&lt;br /&gt;
		[&amp;#039;january&amp;#039;] = 1, [&amp;#039;february&amp;#039;] = 2, [&amp;#039;march&amp;#039;] = 3, [&amp;#039;april&amp;#039;] = 4, [&amp;#039;may&amp;#039;] = 5,&lt;br /&gt;
		[&amp;#039;june&amp;#039;] = 6, [&amp;#039;july&amp;#039;] = 7, [&amp;#039;august&amp;#039;] = 8, [&amp;#039;september&amp;#039;] = 9, [&amp;#039;october&amp;#039;] = 10,&lt;br /&gt;
		[&amp;#039;november&amp;#039;] = 11, [&amp;#039;december&amp;#039;] = 12&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	date_event_string = date_event_string:lower()&lt;br /&gt;
	local ord, day, month = date_event_string:match (&amp;#039;([%a%d]+)%s+(%a+)%s+%a+%s+(%a+)&amp;#039;)&lt;br /&gt;
&lt;br /&gt;
	if is_set(ord) and is_set(day) and is_set(month) then&lt;br /&gt;
		return ordinals[ord], days[day], months[month]&lt;br /&gt;
	else&lt;br /&gt;
		-- if one or more of these not set, then pattern didn&amp;#039;t match&lt;br /&gt;
		return nil&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--[[ get_days_in_month(year, month)&lt;br /&gt;
Returns the number of days in the month where month is a number 1–12&lt;br /&gt;
and year is four-digit Gregorian calendar.&lt;br /&gt;
Accounts for leap year. Throws an error if month and year are not numbers.&lt;br /&gt;
]]&lt;br /&gt;
local function get_days_in_month(year, month)&lt;br /&gt;
	local days_in_month = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}&lt;br /&gt;
	year = tonumber (year)&lt;br /&gt;
	month = tonumber (month)&lt;br /&gt;
	if month == 2 and year%4 == 0 and (year%100 ~= 0 or year%400 == 0) then&lt;br /&gt;
		return 29&lt;br /&gt;
	end&lt;br /&gt;
	return days_in_month [month]&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--[[ get_date_month_day(date_event_string, year)&lt;br /&gt;
Return the date for the day that is the ordinal (nth) day-name in month of the given year&lt;br /&gt;
e.g. &amp;quot;second Friday in June&amp;quot;, 2018 -&amp;gt; 2018-06-08&lt;br /&gt;
]]&lt;br /&gt;
local function get_date_month_day(date_event_string, year)&lt;br /&gt;
	local ord, weekday_num, month = decode_date_event(date_event_string)&lt;br /&gt;
	if not (is_set (ord) and is_set (weekday_num) and is_set (month)) then&lt;br /&gt;
		return nil&lt;br /&gt;
	end&lt;br /&gt;
	if ord == -1 then&lt;br /&gt;
		-- event occurs on the last day-name of the month&lt;br /&gt;
		-- j = t + 7×(n + 1) - (wt - w) mod 7&lt;br /&gt;
		local days_in_month = get_days_in_month (year, month)&lt;br /&gt;
		local ostime = os.time ({[&amp;#039;year&amp;#039;]=year, [&amp;#039;month&amp;#039;]=month, [&amp;#039;day&amp;#039;]=days_in_month})&lt;br /&gt;
		local last_day_of_month = os.date(&amp;#039;%w&amp;#039;, ostime)&lt;br /&gt;
		return month, days_in_month + 7 * (ord + 1) - ((last_day_of_month - weekday_num) % 7)&lt;br /&gt;
	else&lt;br /&gt;
		-- j = 7×n - 6 + (w - w1) mod 7&lt;br /&gt;
		local ostime = os.time({[&amp;#039;year&amp;#039;]=year, [&amp;#039;month&amp;#039;]=month, [&amp;#039;day&amp;#039;]=1})&lt;br /&gt;
		local first_day_of_month = os.date(&amp;#039;%w&amp;#039;, ostime)&lt;br /&gt;
		return month, 7 * ord - 6 + (weekday_num - first_day_of_month) % 7&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
-- set up public functions for debugging&lt;br /&gt;
local p = {}&lt;br /&gt;
p.currentYear = current_year&lt;br /&gt;
p.getDateMonth = function(frame)&lt;br /&gt;
	local m, d = get_date_month_day(frame.args.date, frame.args.year)&lt;br /&gt;
	return m .. &amp;quot;-&amp;quot; .. d&lt;br /&gt;
end&lt;br /&gt;
--[[ getYearMonthDay&lt;br /&gt;
Takes a date string like &amp;quot;second Friday in June&amp;quot; as parameter |date=&lt;br /&gt;
and a year as parameter |year=&lt;br /&gt;
and returns the date in YYYY-MM-DD format, e.g. 2018-06-08&lt;br /&gt;
Other formats are easy to implement.&lt;br /&gt;
]]&lt;br /&gt;
p.getYearMonthDay = function(frame)&lt;br /&gt;
	local args = frame.args or frame:getParent().args&lt;br /&gt;
	local date_event = args.date or mw.text.trim(args[1])&lt;br /&gt;
	local year = args.year or args[2] or current_year()&lt;br /&gt;
	local month, day = get_date_month_day(date_event, year)&lt;br /&gt;
	month = (month&amp;lt;10 and &amp;quot;0&amp;quot; or &amp;quot;&amp;quot;) .. month&lt;br /&gt;
	day = (day&amp;lt;10 and &amp;quot;0&amp;quot; or &amp;quot;&amp;quot;) .. day&lt;br /&gt;
	return year .. &amp;quot;-&amp;quot; .. month .. &amp;quot;-&amp;quot; .. day&lt;br /&gt;
end&lt;br /&gt;
return p&lt;/div&gt;</summary>
		<author><name>imported&gt;Legoktm</name></author>
	</entry>
</feed>