We help IT Professionals succeed at work.

We've partnered with Certified Experts, Carl Webster and Richard Faulkner, to bring you two Citrix podcasts. Learn about 2020 trends and get answers to your biggest Citrix questions!Listen Now

x

Detect 3rd Tuesday of Month

rruth
rruth asked
on
Medium Priority
334 Views
Last Modified: 2013-12-24
Experts,

I need to dynamically display the numeric day of the 3rd Tuesday of every month on a web site. Unfortunately the 3rd Tuesday very rarely falls on the same numerical day. I will use this calulation to dynamically display the date of a club's next meeting that meets on the third Tuesday of every month. Any clues on how to do this would be very appreciated.

Thank you in advance!
Comment
Watch Question

If you just want to display the next meeting (meaning only one meeting in advance):

<cfset curMonth = CreateDate(Year(Now()),Month(Now()),1) />
<cfset tuesday = "" />
<cfloop condition="NOT isDate(tuesday)">
      <cfloop index="i" from="0" to="6">
            <cfif DayOfWeek(DateAdd('d',i,curMonth)) EQ 3>
                  <cfset tuesday = DateAdd('d',i,curMonth) />
                  <cfset third_tuesday = DateAdd('ww',2,tuesday) />
                  <cfoutput>#DateFormat(third_tuesday,"mm/dd/yyyy")#</cfoutput>
                  <cfbreak />
            </cfif>
      </cfloop>
      <cfset curMonth = DateAdd('m',1,curMonth) />
</cfloop>
This custom function will output the Third Tuesday of the month assuming it has not passed.  If it has passed (ie 3rd Wednesday) then it will output the 3rd Tuesday of next month.

<cffunction name="getTuesday" returntype="date" output="false">
  <cfargument name="inputstream" type="any" required="yes">
  <cfloop from="15" to="21" index="i">
    <cfset dateToCheck = CreateDate(Year(inputstream),Month(inputstream),i)>
    <cfif DayOfWeek(dateToCheck) EQ 3>
      <cfset result = dateToCheck>
    </cfif>
  </cfloop>
  <cfif DateFormat(result) LT DateFormat(now())>
    <cfset result = getTuesday(DateAdd('m',1,result))>
  </cfif>
  <cfreturn DateFormat(result,'mmmm dd, yyyy')>
</cffunction>

<cfoutput>#getTuesday(Now())#</cfoutput>

Not the solution you were looking for? Getting a personalized solution is easy.

Ask the Experts
CERTIFIED EXPERT

Commented:

Declare @cd datetime, @Tue3 datetime
Set @cd = '1/may/2006'
Set @Tue3 = DATEADD(wk,2, case when DatePart(dd,DATEADD(dd, 1, DATEADD(wk, DATEDIFF(wk,0, dateadd(dd,6-datepart(day,@cd),@cd)  ), 0))) > 7 then DATEADD(dd, -6, DATEADD(wk, DATEDIFF(wk,0, dateadd(dd,6-datepart(day,@cd),@cd)  ), 0)) else DATEADD(dd, 1, DATEADD(wk, DATEDIFF(wk,0, dateadd(dd,6-datepart(day,@cd),@cd)  ), 0)) end )
Select @Tue3 as T3

T3 from this query will give the 3rd Tuesday for whatever month you put into it.
In this ex you see Set @cd = '1/may/2006' - just change for whatever month you want the info on

This code is for sql server - have not tested on other dbs

Author

Commented:
That is wonderful, works perfect. Is it possible I could get you to explain the loops line by line so I can understand the logic behind the code?

Thank you very much!!!

Author

Commented:
js_vaughan

That's it, exactly what I needed. Could I get you to explain the code below line by line so I can understand the logic?

Thank you very much!!!

  <cfloop from="15" to="21" index="i">
    <cfset dateToCheck = CreateDate(Year(inputstream),Month(inputstream),i)>
    <cfif DayOfWeek(dateToCheck) EQ 3>
      <cfset result = dateToCheck>
    </cfif>
  </cfloop>
  <cfif DateFormat(result) LT DateFormat(now())>
    <cfset result = getTuesday(DateAdd('m',1,result))>
  </cfif>
<cfset curMonth = CreateDate(Year(Now()),Month(Now()),1) />
<cfset tuesday = "" />
<!--- While we have not found a date for tuesday --->
<cfloop condition="NOT isDate(tuesday)">
     <!--- Loop through the first seven days of the first week (where we know there has to be a tuesday) --->
     <cfloop index="i" from="0" to="6">
          <!--- If the day we're at is the third day of the week (tuesday) --->
          <cfif DayOfWeek(DateAdd('d',i,curMonth)) EQ 3>
               <!--- We've found the first tuesday --->
               <cfset tuesday = DateAdd('d',i,curMonth) />
               <!--- By adding two weeks, we'll find the third tuesday --->
               <cfset third_tuesday = DateAdd('ww',2,tuesday) />
               <!--- If the third tuesday is already passed, remove the date from tuesday and go to the next month --->
               <cfif DateCompare(third_tuesday,Now()) LTE 0>
                 <cfset tuesday = "" />
               <cfelse>
                 <!--- Output the date for the third tuesday --->
                 <cfoutput>#DateFormat(third_tuesday,"mm/dd/yyyy")#</cfoutput>
               </cfif>
               <cfbreak />
          </cfif>
     </cfloop>
     <!--- If we didn't find the third tuesday, look at the next month --->
     <cfset curMonth = DateAdd('m',1,curMonth) />
</cfloop>
CERTIFIED EXPERT

Commented:
So I guess you're not using Sql Server?
The post I made really is an excellent solution if you try it. :)

Not saying the others are bad or anything though ...
Sure thing.

<cfloop from="15" to="21" index="i">
- I looped between the 15th and 21st because the first 14 days of a month will have the first 2 occurances of any day, be it monday, tuesday, or saturday.

<cfset dateToCheck = CreateDate(Year(inputstream),Month(inputstream),i)>
- I used that day (between 15 and 21) and put into into the current month and year to create a real date

<cfif DayOfWeek(dateToCheck) EQ 3>
- The DayOfWeek will return a 1-7 depending on the day you are looking for.  Sunday starts at 1, so Tuesday is 3

<cfset result = dateToCheck>
- Once it is found, I save it

<cfif DateFormat(result) LT DateFormat(now())>
- This uses the DateFormat() to wrap the result you just got, and the current date to compare them on equal grounds (cuts off the time of day)

<cfset result = getTuesday(DateAdd('m',1,result))>
- If the result you found was before todays date, then it uses DateAdd to add a month to the result, then restarts the process all over again by calling the function itself

Author

Commented:
js_vaughan,

Ok, I'm almost there. Could you explain the argument "inputstream" and how its used? It looks like it has no value, yet it is being used to set the value of the var dateToCheck.

Thanks again!
Inputstream is just a generic term I always use with functions.  For me, "Inputstream" is what is coming into the function.. and "result" is what it sends back out.  These are really no different than variable names.

You can see my first call to the function was here at the bottom:

#getTuesday(Now())#
- That passed Now() to the function

<cfargument name="inputstream" type="any" required="yes">
- Inside the function, it assigns a name to what is being received.  For me, I just call it inputstream.

So the important part is just that you use <cfargument> to capture what is coming into the function.  "inputstream" is just a variable name
Access more of Experts Exchange with a free account
Thanks for using Experts Exchange.

Create a free account to continue.

Limited access with a free account allows you to:

  • View three pieces of content (articles, solutions, posts, and videos)
  • Ask the experts questions (counted toward content limit)
  • Customize your dashboard and profile

*This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.

OR

Please enter a first name

Please enter a last name

8+ characters (letters, numbers, and a symbol)

By clicking, you agree to the Terms of Use and Privacy Policy.