Getting the Nth Occurrence Of A Day Of The Week For A Given Month

<cffunction
	name="GetNthDayOfMonth"
	access="public"
	returntype="any"
	output="false"
	hint="I return the Nth instance of the given day of the week for the given month (ex. 2nd Sunday of the month).">
 
	<!--- Define arguments. --->
	<cfargument
		name="Month"
		type="date"
		required="true"
		hint="I am the month for which we are gathering date information."
		/>
 
	<cfargument
		name="DayOfWeek"
		type="numeric"
		required="true"
		hint="I am the day of the week (1-7) that we are locating."
		/>
 
	<cfargument
		name="Nth"
		type="numeric"
		required="false"
		default="1"
		hint="I am the Nth instance of the given day of the week for the given month."
		/>
 
	<!--- Define the local scope. --->
	<cfset var LOCAL = {} />
 
	<!---
		First, we need to make sure that the date we were given
		was actually the first of the month.
	--->
	<cfset ARGUMENTS.Month = CreateDate(
		Year( ARGUMENTS.Month ),
		Month( ARGUMENTS.Month ),
		1
		) />
 
 
	<!---
		Now that we have the correct start date of the month, we
		need to find the first instance of the given day of the
		week.
	--->
	<cfif (DayOfWeek( ARGUMENTS.Month ) LTE ARGUMENTS.DayOfWeek)>
 
		<!---
			The first of the month falls on or before the first
			instance of our target day of the week. This means we
			won't have to leave the current week to hit the first
			instance.
		--->
		<cfset LOCAL.Date = (
			ARGUMENTS.Month +
			(ARGUMENTS.DayOfWeek - DayOfWeek( ARGUMENTS.Month ))
			) />
 
	<cfelse>
 
		<!---
			The first of the month falls after the first instance
			of our target day of the week. This means we will
			have to move to the next week to hit the first target
			instance.
		--->
		<cfset LOCAL.Date = (
			ARGUMENTS.Month +
			(7 - DayOfWeek( ARGUMENTS.Month )) +
			ARGUMENTS.DayOfWeek
			) />
 
	</cfif>
 
 
	<!---
		At this point, our Date is the first occurrence of our
		target day of the week. Now, we have to navigate to the
		target occurence.
	--->
	<cfset LOCAL.Date += (7 * (ARGUMENTS.Nth - 1)) />
 
	<!---
		Return the given date. There is a chance that this date
		will be in the NEXT month of someone put in an Nth value
		that was too large for the current month to handle.
	--->
	<cfreturn DateFormat( LOCAL.Date ) />
</cffunction>

For Cut-and-Paste