Solved

next business day function?

Posted on 2004-08-05
15
223 Views
Last Modified: 2013-12-24
Is there a "next business day" function when working with dates, or do I have to do it the 'hard' way?
0
Comment
Question by:theamzngq
  • 8
  • 7
15 Comments
 
LVL 35

Expert Comment

by:mrichmon
Comment Utility
There is not a "nextbusinessday" function, but there is the following which caluclates the number of business days inbetween two days and part of the code could be easily used to test if the current day was a business day or not.

<!--- CF_WorkDateDiff
Syntax: <CF_WorkDateDiff StartDate="StartDate" EndDate="EndDate" ClosedDays="List of dates closed" ReturnVariable="somevarname">
OR
<cfmodule template="CF_WorkDateDiff.cfm" StartDate="StartDate" EndDate="EndDate" ClosedDays="List of dates closed" ReturnVariable="somevarname">

This tag takes a start and end date and calculates the number of working days in between - not counting closed dates.
The result, the number of working days as an integer, is returned in the variable specified by ReturnVariable,
in the calling template's scope. --->

<!--- Tag Parameters --->
<cfparam name="ATTRIBUTES.StartDate" type="date">
<cfparam name="ATTRIBUTES.EndDate" type="date">
<cfparam name="ATTRIBUTES.ClosedDays" type="string" default="">
<cfparam name="ATTRIBUTES.ReturnVariable" type="variablename">

<cfset num_closed = 0><!--- Count closed days that fall in range --->

<!--- Count number of closed days in date range --->
<cfloop index="dayoff" list="#ATTRIBUTES.ClosedDays#">
      <cfif (DateCompare(ATTRIBUTES.StartDate, dayoff) EQ -1) AND (DateCompare(dayoff, Attributes.EndDate) LE 0)>
            <cfset num_closed = num_closed + 1>
      </cfif>
</cfloop>
<cfset start_day = DayOfWeek(ATTRIBUTES.StartDate)>
<cfset end_day = DayOfWeek(ATTRIBUTES.EndDate)>
<cfset date_diff_in_days = DateDiff("d", ATTRIBUTES.StartDate, ATTRIBUTES.EndDate)>
<cfset whole_weeks = date_diff_in_days\7>
<cfset days_left = date_diff_in_days mod 7>

<!-- Count weekends in whole weeks --->
<cfset non_bus_days = whole_weeks * 2>

<!--- Count partial or whole weekends for partial weeks --->
<cfif days_left>
      <cfif end_day EQ 7 OR start_day EQ 7>
            <cfset non_bus_days = non_bus_days + 1>
      <cfelseif start_day GT end_day>
            <cfset non_bus_days = non_bus_days + 2>
      </cfif>
</cfif>

<!--- total business days --->
<cfset bus_days = date_diff_in_days - non_bus_days - num_closed>
<!--- Retunr result to calling template --->
<cfset "Caller.#ATTRIBUTES.ReturnVariable#" = bus_days>
0
 
LVL 35

Assisted Solution

by:mrichmon
mrichmon earned 500 total points
Comment Utility
The other option is that there is a DayOfWeek function.  So you could use logic like

Take currentdate
Loop
     Add one day
     If new date is not (sunday or saturday) and day is not in a list of closed days then break
End Loop
You now have the next business day.
 
0
 
LVL 2

Author Comment

by:theamzngq
Comment Utility
the latter is what I was going to end up doing.  I really like your custom tag, though.  I'll have to see if I come up with a need to use it.
0
 
LVL 35

Expert Comment

by:mrichmon
Comment Utility
You could easily write that into a tag....
0
 
LVL 2

Author Comment

by:theamzngq
Comment Utility
I have never made a custom tag before.  It is something I have been planning to look up.  Perhaps now is the time!
0
 
LVL 35

Accepted Solution

by:
mrichmon earned 500 total points
Comment Utility
Very easy.

Use the above as an example, just change teh calculation.

You define a
<cfparam name="ATTRIBUTES.StartDate" type="date">
for each incoming parameter (in this case the date and maybe a list of closed dates)

Then you do the calcualtion like a normal cf page

Then you return the result like this :
<!--- Retunr result to calling template --->
<cfset "Caller.#ATTRIBUTES.ReturnVariable#" = next_day>

Then simply place the file in the CustomTags directory and call like a normal cf tag

<CF_filename StartDate="#var#" ClosedDates="#var2#" ReturnVariable="nextbusinessday">

Then in the page access
#nextbusinessday#

variable that was set by tag.
0
 
LVL 2

Author Comment

by:theamzngq
Comment Utility
here is my new custom tag:

<cfparam name="attributes.StartDate" type="date">
<cfparam name="attributes.NoOfDays" type="numeric">

<cfset today = attributes.StartDate>
<cfoutput>
<cfset noofbusdays = 0>
<cfloop condition="NoOfBusDays LT attributes.NoOfDays">
      <cfset today = today + CreateTimeSpan(1,0,0,0)>
      <cfif NOT ListFind('1,7',dayofweek(today))>
            <cfset noofbusdays = noofbusdays + 1>noofbusdays - #noofbusdays#<br>
            <font color="##00FF00">Today #dateformat(today)# is #dayofweekasstring(dayofweek(today))#</font><br>
      <cfelse>
            Today #dateformat(today)# is #dayofweekasstring(dayofweek(today))#<br>
      </cfif>
</cfloop>
</cfoutput>
<cfset "Caller.#ATTRIBUTES.ReturnVariable#" = businessDay>


When I run it I get an error: Element RETURNVARIABLE is undefined in ATTRIBUTES.

Any ideas?

0
Free Trending Threat Insights Every Day

Enhance your security with threat intelligence from the web. Get trending threat insights on hackers, exploits, and suspicious IP addresses delivered to your inbox with our free Cyber Daily.

 
LVL 2

Author Comment

by:theamzngq
Comment Utility
I fixed the error by doing some more reading on custom tags.  The last line in the tag now reads:
<cfset Caller.businessDay = dateformat(today)>

Thanks for your help!  I might have taken a while to get around to writing some custom tags without this thread.  My father, a programmer from way back, was advising me to start to modularize my code in such a way that I could re-use things (like writing custom tags) to minimize bugs and troubleshooting.  I see the advantages and wisdom now...
0
 
LVL 2

Author Comment

by:theamzngq
Comment Utility
with out my display stuff in it:

<cfparam name="attributes.StartDate" type="date">
<cfparam name="attributes.NoOfDays" type="numeric">

<cfset today = attributes.StartDate>
<cfoutput>
<cfset noofbusdays = 0>
<cfloop condition="NoOfBusDays LT attributes.NoOfDays">
      <cfset today = today + CreateTimeSpan(1,0,0,0)>
      <cfif NOT ListFind('1,7',dayofweek(today))>
            <cfset noofbusdays = noofbusdays + 1>
      </cfif>
</cfloop>
</cfoutput>
<cfset Caller.businessDay = dateformat(today)>
0
 
LVL 35

Expert Comment

by:mrichmon
Comment Utility
Sorry - just got the email messages saying you updated this post....

The problem with the way you fixed it is that you are forcing the user to define a variable called businessDay in the page that will be calling this tag.

The better way to fix it is to add the follwowing code (1 line inserted below indicated in comments) which allows the user to name the variable whatever they want :

================================================

<cfparam name="attributes.StartDate" type="date">
<cfparam name="attributes.NoOfDays" type="numeric">

<!--- Add the following line --->
<cfparam name="ATTRIBUTES.ReturnVariable" type="variablename">

<cfset today = attributes.StartDate>
<cfoutput>
<cfset noofbusdays = 0>
<cfloop condition="NoOfBusDays LT attributes.NoOfDays">
     <cfset today = today + CreateTimeSpan(1,0,0,0)>
     <cfif NOT ListFind('1,7',dayofweek(today))>
          <cfset noofbusdays = noofbusdays + 1>
     </cfif>
</cfloop>
</cfoutput>
<cfset Caller.businessDay = dateformat(today)>

================================================

Then it would be called as

<CF_filename StartDate="#startday#" NoOfDays="1" returnvariable="businessday">

(assuming you had <cfset Startday = "3/01/2004"> above in the page)
0
 
LVL 35

Expert Comment

by:mrichmon
Comment Utility
Oh and the last line would be changed back to :
<cfset "Caller.#ATTRIBUTES.ReturnVariable#" = businessDay>
0
 
LVL 2

Author Comment

by:theamzngq
Comment Utility
shouldn't it be

<cfset Caller..#ATTRIBUTES.ReturnVariable# = dateformat(today)>

?
0
 
LVL 2

Author Comment

by:theamzngq
Comment Utility
too many periods....hehe

<cfset Caller.#ATTRIBUTES.ReturnVariable# = dateformat(today)>
0
 
LVL 2

Author Comment

by:theamzngq
Comment Utility
This is my final answer:

<cfset "Caller.#ATTRIBUTES.ReturnVariable#" = dateformat(today)>
0
 
LVL 35

Expert Comment

by:mrichmon
Comment Utility
:o)
0

Featured Post

Free Trending Threat Insights Every Day

Enhance your security with threat intelligence from the web. Get trending threat insights on hackers, exploits, and suspicious IP addresses delivered to your inbox with our free Cyber Daily.

Join & Write a Comment

Article by: kevp75
Hey folks, 'bout time for me to come around with a little tip. Thanks to IIS 7.5 Extensions and Microsoft (well... really Windows 8, and IIS 8 I guess...), we can now prime our Application Pools, when IIS starts. Now, though it would be nice t…
Meet the world's only “Transparent Cloud™” from Superb Internet Corporation. Now, you can experience firsthand a cloud platform that consistently outperforms Amazon Web Services (AWS), IBM’s Softlayer, and Microsoft’s Azure when it comes to CPU and …
Here's a very brief overview of the methods PRTG Network Monitor (https://www.paessler.com/prtg) offers for monitoring bandwidth, to help you decide which methods you´d like to investigate in more detail.  The methods are covered in more detail in o…
This demo shows you how to set up the containerized NetScaler CPX with NetScaler Management and Analytics System in a non-routable Mesos/Marathon environment for use with Micro-Services applications.

744 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

16 Experts available now in Live!

Get 1:1 Help Now