Exit
  • Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
  • 한국 커뮤니티
0

How to retrieve the date of every Monday of the year.

New Here ,
Dec 28, 2009 Dec 28, 2009

I'm trying to figure out how I can determine the actual dates of a particular day throughout a year.  For instance, does CF have a function that will help me find the dates for every monday throughout 2010?

Thanks!

Paul

TOPICS
Getting started
2.0K
Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines

correct answers 1 Correct answer

Community Expert , Dec 29, 2009 Dec 29, 2009

<cffunction name="getDatesFromDayOfWeek" output="false" returntype="struct">

    <cfargument name="dayOfWeek" required="true" type="string">

    <cfargument name="year" required="true" type="numeric">

    <!--- initialize --->

    <cfset var d = 0>

    <cfset var weekNo = 0>

    <cfset var day = "">

    <cfset var currentDate = "">

    <cfset var dayAsString = "">

    <cfset var days = "Sunday,Monday,Tuesday,Wednesday,Thursday,Friday,Saturday">

    <!--- index of given day in days list --->

    <cfset var

...
Translate
LEGEND ,
Dec 28, 2009 Dec 28, 2009

DayOfTheWeekAsString() tells you if today is a Monday.

Now() tells you the current date and time.

Year() tells you if it's 2010.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Dec 28, 2009 Dec 28, 2009

Right, I'm looking at all the date functions in CF trying to piece it all together, was wondering if somebody has already done it or if someone could help me figure out what I'd need to do.

The path I'm on now is coming from todays date, figuring out the current day, using that marker to determine where the desired day is and then just DateAdd(ing) it every 7 days for the year.

Does that sound right?

Paul

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Valorous Hero ,
Dec 28, 2009 Dec 28, 2009

That's how I would probably approach this.

First find one Monday.  Once the date of one Monday is known all the others can be found by adding or subtracting multiples of 7 to that date.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Dec 28, 2009 Dec 28, 2009

I'd use a slight variation.  Instead of starting from today's date, start from 2010-01-01 (use createdate for this).  Then, use DayOfWeek to see what day that is.  At this point, do a bit of math to determine two things.  One, how many days do you need to add the the 1st of the year to get the first Monday.  Second, how many Mondays will there be in the year.

Then it's a simple loop.

If you do it well, you can use the same code for any year and any day of the week by simply changing two variables.  If you do it really well you'll write it as a function to which you send two arguments.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Dec 29, 2009 Dec 29, 2009

My themes are similar, but different. In any case, they are too numerous to mention. So here's the pudding.

<cffunction name="getDatesFromDayOfWeek" output="false" returntype="struct">
    <cfargument name="dayOfWeek" required="true" type="string">
    <cfargument name="year" required="true" type="numeric">
    <!--- initialize --->
    <cfset var day = "">
    <cfset var dayAsString = "">
    <cfset var days = "Sunday,Monday,Tuesday,Wednesday,Thursday,Friday,Saturday">
    <!--- index of given day in days list --->
    <cfset var dayIndex = listFindNoCase(days, arguments.dayOfWeek)>
    <cfset var result = structnew()>
    <cfset result.isInputValid=false>
    <cfset result.dates = arrayNew(1)>
    <!--- validate input --->
    <cfif dayIndex NEQ 0 and isNumeric(arguments.year) and arguments.year GT 0>
        <cfset result.isInputValid=true>
    </cfif>
    <cfif result.isInputValid>
       
        <cfloop index="d" from="1" to="7">
            <!--- day in first week (of January) of the given year --->
            <cfset day = createDate(arguments.year,1,d)>
            <!--- day name (in the language of the locale!) --->
            <cfset dayAsString = dayofWeekAsString(dayOfWeek(day),getLocale())>
            <!--- find match with the given day--->
            <cfif dayAsString is arguments.dayOfWeek>
                <cfset result.dates[1]= day>
                <!---  roll out the rest of the week-days of the year sharing same day name --->
                <cfloop from="1" to="52" index="weekNo">
                    <!--- week 53 may lap over to next year --->
                    <cfif year(dateAdd("ww",weekNo,day)) EQ arguments.year>
                        <!--- following week --->
                        <cfset result.dates[weekNo+1]= dateAdd("ww",weekNo,day)>
                    </cfif>
                </cfloop>
            </cfif>   
        </cfloop>
    </cfif>   
    <cfreturn result>   
</cffunction>

Example 1): Saterdays in 2008<br>
<cfset result = getDatesFromDayOfWeek("Saterday",2008)>
<cfdump var="#result#">
<hr>
Example 2): Sundays in 2010
<cfset result = getDatesFromDayOfWeek("Sunday",2010)>
<cfdump var="#result#">

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Dec 29, 2009 Dec 29, 2009

There's a coupla fixes I'd make to that:

1) it'll only work with an English locale, because you hard-code that day-of-week list in ENglish, so the dayIndex test will fail if the input string is not an English day name, and never get to the bit where you switch be being local-specific.

2) you're not VARing your loop indexes.

3) you don't need the outer loop.  You don't need to walk through the days of the week to find the date of the requested day, you can simply infer where the next one is from the DOW of Jan 1.

4) and you should be breaking out of the outer loop once you find the specified DOW anyhow... as it stands you continue looping through the rest of the week once you've found the day you want, which is a bit redundant.

5) I'd do the dateAdd operation once, and then use its result in both the IF and the array assignment.  Rather than doing it once each for those operations.

6) I'd raise an exception if the input was invalid, rather than passing back a flag with the results. This is more in-keeping with hour built-in functions work.  This is just personal preference though.

But the techique of wrapping up the desired functionality in a function is a worthy suggestion.

--

Adam

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Dec 29, 2009 Dec 29, 2009

A Cameron, thanks for the remarks. I agree with some, disagree with some.

it'll only work with an English locale, because you hard-code that
day-of-week list in ENglish,

I agree with this part: this is to work in English.

so the dayIndex test will fail if the input string is not an English day name, and never get to the bit where you switch be being local-specific.

Not quite. I wanted to avoid the case where the input is an English day name, but dayOfWeekAsString() returns, for example,  Montag, Dienstag, Mittwoch, etc. In any case, your remark alerted me to the proper function. It should be setLocale(), not getLocale().


you're not VARing your loop indexes.

You're right. An oversight. Consider them varred.

you don't need the outer loop.  You don't need to walk through the
days of the week to find the date of the requested day, you can simply
infer where the next one is from the DOW of Jan 1.

The outer loop is to find the name that matches the input string, not to find a date.

you should be breaking out of the outer loop once you find the specified DOW anyhow

True. Break inserted.

I'd do the dateAdd operation once, and then use its result in both the
IF and the array assignment.  Rather than doing it once each for those
operations.

Yes, but then you'll have to create the date objects later. DateAdd creates them at once.

I'd raise an exception if the input was invalid, rather than passing
back a flag with the results. This is more in-keeping with hour
built-in functions work.

It isn't an either-or. I have in fact made room for exception handling. You may waltz it like this

<cfif result.isInputValid>

<!--- yer business --->

<cfelse>

<cfthrow etc. etc.>

</cfif>

Thanks for the feedback. The improved version follows.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Dec 29, 2009 Dec 29, 2009

<cffunction name="getDatesFromDayOfWeek" output="false" returntype="struct">

    <cfargument name="dayOfWeek" required="true" type="string">

    <cfargument name="year" required="true" type="numeric">

    <!--- initialize --->

    <cfset var d = 0>

    <cfset var weekNo = 0>

    <cfset var day = "">

    <cfset var currentDate = "">

    <cfset var dayAsString = "">

    <cfset var days = "Sunday,Monday,Tuesday,Wednesday,Thursday,Friday,Saturday">

    <!--- index of given day in days list --->

    <cfset var dayIndex = listFindNoCase(days, arguments.dayOfWeek)>

    <cfset var result = structnew()>

    <cfset result.isInputValid=false>

    <cfset result.dates = arrayNew(1)>

    <!--- validate input --->

    <!--- added: validation, year must be int --->

    <cfif dayIndex NEQ 0 and isNumeric(arguments.year) and arguments.year GT 0 and int(arguments.year) EQ arguments.year>

        <cfset result.isInputValid=true>

    </cfif>

    <cfif result.isInputValid>

         <!--- added: get out of loop when date matched, and set locale. Thanks to A. Cameron's feedback  --->

        <cfloop index="d" from="1" to="7">

            <!--- day in first week (of January) of the given year --->

            <cfset day = createDate(arguments.year,1,d)>

            <!--- day name (in the language of the locale!) --->

            <cfset dayAsString = dayofWeekAsString(dayOfWeek(day),setLocale("English (US)"))>

            <!--- find match with the given day--->

            <cfif dayAsString is arguments.dayOfWeek>

                <cfset result.dates[1]= day>

                <cfbreak>

            </cfif>

        </cfloop>

           

       <!---  roll out the rest of the week-days of the year sharing same day name --->

       <cfloop from="1" to="52" index="weekNo">

           <cfset currentdate = dateAdd("ww",weekNo,day)>

           <!--- week 53 may lap over to next year --->

           <cfif year(currentdate) EQ arguments.year>

               <!--- following week --->

               <cfset result.dates[weekNo+1]= currentdate>

           </cfif>

       </cfloop>

    </cfif>  

    <cfreturn result>  

</cffunction>

Example 1): Saterdays in 2008<br>

<cfset result = getDatesFromDayOfWeek("Saterday",2008)>

<cfdump var="#result#">

<hr>

Example 2): Sundays in 2010

<cfset result = getDatesFromDayOfWeek("Sunday",2010)>

<cfdump var="#result#">

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Dec 29, 2009 Dec 29, 2009

Thanks BKBK that's pretty handy! Works great!

Paul

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Engaged ,
Dec 29, 2009 Dec 29, 2009

This SQL script might be helpful. Though this is not a CF solutions - but if you have SQL in the project then this might help.

Thanks

Sankalan

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Dec 29, 2009 Dec 29, 2009

What sql script?

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Engaged ,
Dec 29, 2009 Dec 29, 2009
LATEST
Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Resources