Find The Date Of The First Instance Of A Weekday In A Month

Author: Steven Neiland
Published:

Warning: This blog entry was written two or more years ago. Therefore, it may contain broken links, out-dated or misleading content, or information that is just plain wrong. Please read on with caution.

As a follow up on my previous post on calculating week numbers for a month, today I am going to show how to work out the first date in a month that a given weekday occurs on.

Again this is useful when dealing with financial reporting tools where you might need to find the first wednesday of this month. You can then extrapolate out the 2nd 3rd 4th instances for the same weekday.

I think the comments explain the logic fairly well so I wont go pulling it apart. If you have a question please leave a comment and I'll try answer as best I can. Oh and yeah I know the function name is very verbose but that is just to help explain what it is going on here, feel free to shorten it.

<cffunction name="firstInstanceOfWeekDayInMonth" access="public" output="true" 
      hint="Find the date first instance of a specific week day in a month">

      
      <cfargument name="testDate" required="true" type="date">
      <cfargument name="findDay" required="true" type="numeric">
      
      <!--- Find the first day of the month --->
      <cfset var dtMonthStart =
            createDate(year(arguments.testDate),month(arguments.testDate),1)>


      <!--- Find the weekday number of first day of the month --->
      <cfset var firstWeekDayOfMonth = dayOfWeek(dtMonthStart)>

      <cfset var firstDate = "">
      <cfset var difference = 0>
      
      <!---
            As a quick sanity check throw an error if the weekday being
            searched for is not in the range 1-7
      --->

      <cfif arguments.findDay LT 1 OR arguments.findDay GT 7>
            <cfthrow message="Target day to search on is not in the range 1-7">
      </cfif>
      
      <!--- If the first day of the month is also the day we want --->
      <cfif firstWeekDayOfMonth EQ arguments.findDay>
            <cfset firstDate = dtMonthStart>
      
      <!--- If the first day of the month is later in the week --->
      <cfelseif firstWeekDayOfMonth GT arguments.findDay>
            <cfset difference = firstWeekDayOfMonth - arguments.findDay>
            <cfset firstDate = dateAdd("d",(7-difference),dtMonthStart)>
            
      <!--- If the first day of the month is earlier in the week --->
      <cfelse>
            <cfset firstDate
            = dateAdd("d",(arguments.findDay-firstWeekDayOfMonth),dtMonthStart)>

      </cfif>

      <cfreturn firstDate>
</cffunction>

Related Blog Postings

Reader Comments

Adam Cameron's Gravatar
Adam Cameron
Tuesday, September 18, 2012 at 6:39:52 AM Coordinated Universal Time

G'day:
It might be worth submitting this function to CFLib? I'm sure other people could benefit from it.

Cheers for the article.

--
Adam

Steven Neiland's Gravatar
Steven Neiland
Tuesday, September 18, 2012 at 8:12:00 PM Coordinated Universal Time

Thanks Adam,
Thats a good idea. I have one or two more functions queued up in my drafts folder. Once I get around to them I'll wrap them up in a cfc and submit to cflib.

  • Please keep comments on-topic.
  • Please do not post unrelated questions or large chunks of code.
  • Please do not engage in flaming/abusive behaviour.
  • Comments that contain advertisments or appear to be created for the purpose of link building, will not be published.

Archives Blog Listing