Quick Puzzler - Get Last Friday

Posted By : todd sharp Posted At : October 27, 2009 1:49 PM Posted In: ColdFusion

14

Here's a quick puzzler to get your brain working. I just helped out a friend with the following issue but I'm interested in seeing how others go about solving it. I'll borrow Ray's Friday Puzzler rules - don't spend more then 5 minutes on it and the best solution is granted 1,794 bonus points.

Write a UDF that solves the following puzzle: If it is any day or time after noon on Friday (server time) then set 'reportDate' equal to the current date. If it's any day or time before noon on Friday then set 'reportDate' to last Friday. Sounds easy, but it can get a little tricky.

Post your entry in the comments below.

Comments (14)

Saravanamuthu's Gravatar I hope, It will work. :)

<cfscript>

function lastFriday(ipDay){
if( dayOfWeek(ipDay) gt 5 or (dayOfWeek(ipDay) eq 5 and hour(ipDay) gt 12) )
   return ipDay;
else
   return dateAdd('d',-dayOfWeek(ipDay)-1,ipDay);
}   
         
</cfscript>

Quan Tran's Gravatar Maybe it's just me, but the description has me confusing.

I assume you mean the current friday? when refering to:

any day or time after noon on Friday
any day or time before noon on Friday

todd sharp's Gravatar @Quan - Yes, the current friday.

@Saravanamuthu: Almost, but that didn't catch Saturday, Ex:

<p>#lastFriday(createDateTime(2009,10,24,11,59,00))#</p>

returns {ts '2009-10-24 11:59:00'} (saturday)

todd sharp's Gravatar @Saravanamuthu -- also, it should be hour(ipDay) gte 12, not just gt ;)

Quan Tran's Gravatar not a udf, but:

<cfset CurrentFriday = dateadd("d",6-dayofweek(now()),now()) />
<cfset CurrentFriday = CreateDateTime(year(CurrentFriday), month(CurrentFriday), day(CurrentFriday), 12, 0, 0) />

<cfoutput><cfif DateTimeInQuestion gt CurrentFriday>#DateTimeInQuestion#<cfelse>#dateadd("ww",-1,CurrentFriday)#</cfif></cfoutput>

Steve Withington's Gravatar probably a bit verbose, but this should work:

<cffunction name="getReportDate"
         output="false"
         returntype="date"
         hint="If it is any day or time after noon on Friday (server time) then set 'local.reportDate' = currFriday, else lastFriday."
         access="remote">   
   <cfargument name="theDate" default="#dateformat(now(), 'mm/dd/yyyy')#" type="date" />
   <cfset var local = structNew() />
   <cfswitch expression="#dayofweek(arguments.theDate)#">
      <!--- sun --->
      <cfcase value="1">
         <cfset local.reportDate = dateadd("d", -2, theDate) />
      </cfcase>
      <!--- mon --->
      <cfcase value="2">
         <cfset local.reportDate = dateadd("d", -3, theDate) />
      </cfcase>
      <!--- tue --->
      <cfcase value="3">
         <cfset local.reportDate = dateadd("d", -4, theDate) />
      </cfcase>
      <!--- wed --->
      <cfcase value="4">
         <cfset local.reportDate = dateadd("d", -5, theDate) />
      </cfcase>
      <!--- thur --->
      <cfcase value="5">
         <cfset local.reportDate = dateadd("d", -6, theDate) />
      </cfcase>
      <!--- fri --->
      <cfcase value="6">
         <cfif hour(theDate) lt 12>
            <cfset local.reportDate = dateadd("d", -7, theDate) />
            <cfelse>
            <cfset local.reportDate = theDate />
         </cfif>
      </cfcase>
      <!--- sat --->
      <cfcase value="7">
         <cfset local.reportDate = dateadd("d", -2, theDate) />
      </cfcase>   
   </cfswitch>
   <cfreturn dateformat(local.reportDate, 'mm/dd/yyyy') />
</cffunction>
<cfoutput>#getReportDate()#</cfoutput>

Steve Withington's Gravatar caught a minor error on saturday. oops.


<cffunction name="getReportDate"
output="false"
returntype="date"
hint="If it is any day or time after noon on Friday (server time) then set 'local.reportDate' = currFriday, else lastFriday."
access="remote">
<cfargument name="theDate" default="#dateformat(now(), 'mm/dd/yyyy')#" type="date" />
<cfset var local = structNew() />
<cfswitch expression="#dayofweek(arguments.theDate)#">
<!--- sun --->
<cfcase value="1">
<cfset local.reportDate = dateadd("d", -2, theDate) />
</cfcase>
<!--- mon --->
<cfcase value="2">
<cfset local.reportDate = dateadd("d", -3, theDate) />
</cfcase>
<!--- tue --->
<cfcase value="3">
<cfset local.reportDate = dateadd("d", -4, theDate) />
</cfcase>
<!--- wed --->
<cfcase value="4">
<cfset local.reportDate = dateadd("d", -5, theDate) />
</cfcase>
<!--- thur --->
<cfcase value="5">
<cfset local.reportDate = dateadd("d", -6, theDate) />
</cfcase>
<!--- fri --->
<cfcase value="6">
<cfif hour(theDate) lt 12>
<cfset local.reportDate = dateadd("d", -7, theDate) />
<cfelse>
<cfset local.reportDate = theDate />
</cfif>
</cfcase>
<!--- sat --->
<cfcase value="7">
<cfset local.reportDate = dateadd("d", -1, theDate) />
</cfcase>
</cfswitch>
<cfreturn dateformat(local.reportDate, 'mm/dd/yyyy') />
</cffunction>
<cfoutput>#getReportDate()#</cfoutput>

Saravanamuthu's Gravatar Hi todd, I corrected it. :)
<cfscript>
function lastFriday(ipDay){
if( dayOfWeek(ipDay) eq 6 and hour(ipDay) gte 12 )
return ipDay;
else if (dayOfWeek(ipDay) lt 6)
return dateAdd('d',-dayOfWeek(ipDay)-1,ipDay);
else
return dateAdd('d',6-dayOfWeek(ipDay),ipDay);
}
</cfscript>

Matthew's Gravatar <cffunction name="getFriday" returntype="date">
   <cfargument name="d" required="no" default="#now()#">
      <cfif DayOfWeek(ARGUMENTS.d) eq 6 and hour(ARGUMENTS.d) gte 12>
<cfreturn ARGUMENTS.d>
<cfelseif DayOfWeek(ARGUMENTS.d) lt 6>
<cfreturn DateAdd('d',-DayOfWeek(ARGUMENTS.d)-1,ARGUMENTS.d)>
<cfelseif DayOfWeek(ARGUMENTS.d) gt 6>
<cfreturn DateAdd("d",-1,ARGUMENTS.d)>
<cfelse>
<cfreturn DateAdd("d",-(7 - (6 - DayOfWeek(ARGUMENTS.d))),ARGUMENTS.d)>
</cfif>
</cffunction>

Steve Withington's Gravatar @Saravanamuthu, actually, you forgot to account for time before noon on Friday:

<cfscript>
function lastFriday(ipDay){
   if ( dayOfWeek(ipDay) eq 6 and hour(ipDay) gte 12 ) {
      return ipDay;
   } else if ( dayOfWeek(ipDay) lt 6 or dayOfWeek(ipDay) eq 6 and hour(ipDay) lt 12 ) {
      return dateAdd('d',-dayOfWeek(ipDay)-1,ipDay);
   } else {
      return dateAdd('d',6-dayOfWeek(ipDay),ipDay);
   }
}
</cfscript>

Quan Tran's Gravatar here's my version wrapped in a udf:

<cfscript>
function lastfriday(inputdate){
   var CurrentFriday = dateadd("d",6-dayofweek(now()),now());
   CurrentFriday = CreateDateTime(year(CurrentFriday), month(CurrentFriday), day(CurrentFriday), 12, 0, 0);

   if (inputdate gt CurrentFriday)
      return arguments.inputdate;
   else
      return dateadd("ww",-1,CurrentFriday);
}
</cfscript>


I'm curious what you came up with.

todd sharp's Gravatar Nice solutions! Here's what I came up with -- pretty similar to what everyone here has done:

<cfset d = createDateTime(2009,10,24,11,59,00) />

<cfif hour(d) gte 12 and dayOfWeek(d) gte 6>
   <cfset dow = dayOfWeek(d) />
   <cfset friday = dateDiff()>
   <cfset reportDate = d />
<cfelseif dayOfWeek(d) eq 7>
   <cfset reportDate = dateAdd("d", -1, d)>
<cfelse>
   <cfset lastWeek = dateAdd("ww", -1, d) />
   <cfset thisDayLastWeek = dayOfWeek(lastWeek) />
   <cfset daysFromLastFriday = 6 - thisDayLastWeek />
   <cfset reportDate = dateAdd("d", daysFromLastFriday, lastWeek) />
</cfif>

todd sharp's Gravatar oops that's not right - hang on a second...

todd sharp's Gravatar <cfset d = createDateTime(2009,10,24,11,59,00) />

<cfif hour(d) gte 12 and dayOfWeek(d) eq 6>
<cfset reportDate = d />
<cfelseif dayOfWeek(d) eq 7>
<cfset reportDate = dateAdd("d", -1, d)>
<cfelse>
<cfset lastWeek = dateAdd("ww", -1, d) />
<cfset thisDayLastWeek = dayOfWeek(lastWeek) />
<cfset daysFromLastFriday = 6 - thisDayLastWeek />
<cfset reportDate = dateAdd("d", daysFromLastFriday, lastWeek) />
</cfif>