--[[ Calculates the Gregorian date of a recurring holiday that varies year-to-year, but follows the rule "Nth [day of week] of [month]" "month" = month number (1 to 12) "weeknumber" = number of week (1 to 4, or -1 to mean "last") "dayofweek" = number that represents the day of the week, where 1 = Sunday and 7 = Saturday "year" = Gregorian calendar year ]]require('Module:No globals')localp={}functionp.calculate(frame)localargs=frame.argslocalONE_DAY=86400-- number of seconds in one daylocalyear=tonumber(args.year)localmonth=tonumber(args.month)localweeknumber=tonumber(args.weeknumber)localdayofweek=tonumber(args.dayofweek)localdate=os.time{year=year,month=month,day=1}localdateparts=os.date("*t",date)ifweeknumber>0then-- find the first [dayofweek] of this monthwhiledateparts["wday"]~=dayofweekdodate=date+ONE_DAYdateparts=os.date("*t",date)end-- add the correct number of weeksifweeknumber>1thendate=date+((weeknumber-1)*(7*ONE_DAY))endelse-- find the first day of the next monthwhiledateparts["month"]==monthdodate=date+ONE_DAYdateparts=os.date("*t",date)end-- go back one day to get the last day of the month we wantdate=date-ONE_DAYdateparts=os.date("*t",date)-- go backwards until we find the right day of weekwhiledateparts["wday"]~=dayofweekdodate=date-ONE_DAYdateparts=os.date("*t",date)endendlocalresult=os.date("%Y-%m-%d",date)returnresultendreturnp