Simple date math to get the Sunday for a given date

This post is more than 2 years old.

This is something that I struggled with that I guarantee could have been done a lot simpler. I can't figure out what the simpler solution is - but I'm convinced it exists. Given an arbitrary date, like March 27, how would you get the Sunday for that week? Why would you even want to do that? You may want to collapse data points for items in the same week to one value specified by that week's Sunday. You could then display it as: Week of March 25.

To do this, I used the following date math:

<cfset theSunday = dateAdd("d", -1 * (dayOfWeek(theDate)-1),theDate)>

I then wrote up a simple test to demonstrate the logic:

<cfset theDate = now()> <cfloop index="x" from="1" to="50"> <cfset theSunday = dateAdd("d", -1 * (dayOfWeek(theDate)-1),theDate)> <cfoutput>The Date is #dateFormat(theDate)#, week of #dateFormat(theSunday)#<br/></cfoutput> <cfset theDate = dateAdd("d", 2, theDate)> </cfloop>

Here's part of the output:

The Date is 27-Mar-12, week of 25-Mar-12 The Date is 29-Mar-12, week of 25-Mar-12 The Date is 31-Mar-12, week of 25-Mar-12 The Date is 02-Apr-12, week of 01-Apr-12 The Date is 04-Apr-12, week of 01-Apr-12 The Date is 06-Apr-12, week of 01-Apr-12 The Date is 08-Apr-12, week of 08-Apr-12 The Date is 10-Apr-12, week of 08-Apr-12 The Date is 12-Apr-12, week of 08-Apr-12 The Date is 14-Apr-12, week of 08-Apr-12 The Date is 16-Apr-12, week of 15-Apr-12 The Date is 18-Apr-12, week of 15-Apr-12 The Date is 20-Apr-12, week of 15-Apr-12 The Date is 22-Apr-12, week of 22-Apr-12 The Date is 24-Apr-12, week of 22-Apr-12 The Date is 26-Apr-12, week of 22-Apr-12 The Date is 28-Apr-12, week of 22-Apr-12 The Date is 30-Apr-12, week of 29-Apr-12 The Date is 02-May-12, week of 29-Apr-12 The Date is 04-May-12, week of 29-Apr-12

Raymond Camden's Picture

About Raymond Camden

Raymond is a senior developer evangelist for Adobe. He focuses on document services, JavaScript, and enterprise cat demos. If you like this article, please consider visiting my Amazon Wishlist or donating via PayPal to show your support. You can even buy me a coffee!

Lafayette, LA https://www.raymondcamden.com

Archived Comments

Comment 1 by Jason posted on 3/28/2012 at 6:53 AM

Interesting - I had to do something similar for a project this past week. It's a scheduling app where I need to know what the start and end of the week (Sunday to Saturday) is based on a user specified date. I was new to using FIX with dates but what a great little feature. Converting dates to numbers made it easy.

dtThisWeek = fix( *userdate* )
objThisWeek = structNew()
objThisWeek.Start = dateFormat(dtThisWeek - dayOfWeek( dtThisWeek ) + 1)
objThisWeek.End = dateFormat( objThisWeek.Start + 6 )

Comment 2 by Gert Franz posted on 3/28/2012 at 12:49 PM

Here you go:

<cfset dSunday = int(now()/7)*7+1>
or
<cfset dSunday = now() - now() % 7 + 1>

Since we know the date that equals to 0 is the 30st of December 1899 and that was a Saturday, you can easily use one of the two above approaches in order to find the closest sunday.

HTH

Gert

Comment 3 by Mark posted on 3/28/2012 at 4:34 PM

I wrote a PHP function like this for my church's website, but I was looking for the next Sunday rather than the previous Sunday. It was just a matter of incrementing the passed date (today) in a loop until the date('l',strtotime($passedDate)) equaled 'Sunday'. I'd imagine the same thing could be done by decrementing the passed date and using CF's DayOfWeekAsString function.

Comment 4 by David Boyer posted on 3/28/2012 at 4:49 PM

@Gert, nice approach that's going into my snippets ;)

It'd be nice to have a way to request relative dates like (dare I say it...) the PHP strToTime function (http://www.php.net/manual/e.... I have played around with a Java library that provides something similar but stumbled into a bug with specifying days (rrd4j - http://rrd4j.googlecode.com....

Comment 5 by David Boyer posted on 3/28/2012 at 4:54 PM

@Mark, easy way to get next Sunday in PHP is: date("Y-m-d l", StrToTime("Sunday"))
:)

@Ray, sorry for mentioning PHP twice on your blog :/

Comment 6 by Raymond Camden posted on 3/28/2012 at 5:30 PM

@Gert: I tried to read your comment, but every time I did my brain bled a bit and I gave up. ;)

@David: No worries at all - I've seen that strToTime function and it's REALLY cool.

On a totally unrelated note - I noticed that Mail on my iPad will notice stuff like "tomorrow morning" and "Monday morning" and offer to create an event for it. That is SUPER cool - and I plan on trying to recreate that myself.

Comment 7 by Gert Franz posted on 3/28/2012 at 6:52 PM

@Ray: Well all I do is to take the current day as a float and by dividing it by 7 and cutting of the decimals I get the number of weeks (X) since 12/30/1899. Then multiply it by 7 and then I get the Saturday which is X weeks after 12/30/1899. And since that day was a Saturday I have to add one. Hence the formula. The second version is actually the exact same thing written with the modulo operator. HTH :-)

Comment 8 by Raymond Camden posted on 3/28/2012 at 6:54 PM

Math scary. Hulk smash.

Comment 9 by Tim Garver posted on 3/28/2012 at 11:55 PM

I did this about 9 years ago and is not as elegant but here goes:
[code]
<!--- td = today or what ever date --->
<cfset td = dateAdd('d',-4,now())>
<cfset ToDay = DayOfWeek(td)>
<CFIF ToDay EQ 1>
<cfset lastsunday = DATEADD('d',-7,td)>
<cfset sunday = td>
<cfelseif today EQ 2>
<cfset lastsunday = DATEADD('d',-8,td)>
<cfset sunday = DATEADD('d',-1,td)>
<cfelse>
<cfset tmp = today - 1>
<cfset lastsunday = DATEADD('d',-(tmp+7),td)>
<cfset sunday = DATEADD('d',-tmp,td)>
</cfif>

[/code]

This will give you this weeks Sunday as a beginning to the week as well as the previous Sunday.
I know its a bit bloated but it works or at least i think it does :)

Tim

Comment 10 by Raymond Camden posted on 3/28/2012 at 11:57 PM

I love the caps. Believe it or not - I used to do all my ColdFusion in caps. -shudder-

Comment 11 by Michael posted on 3/29/2012 at 6:41 PM

I did this in javascript recently:
getSundayFollowing: function(dt)
{
var endOfWeekVal = new Date(dt);
var dayOfWeek = endOfWeekVal.getDay();
if ( dayOfWeek > 0 )
{
endOfWeekVal.setDate(endOfWeekVal.getDate() + (7-dayOfWeek));
}
return endOfWeekVal;
},