Please start any new threads on our new site at https://forums.sqlteam.com. We've got lots of great SQL Server experts to answer whatever question you can come up with.

 All Forums
 SQL Server 2000 Forums
 SQL Server Development (2000)
 Calculate working days

Author  Topic 

Pinto
Aged Yak Warrior

590 Posts

Posted - 2005-03-07 : 10:20:49
Sorry for all these questions.... Has anyone an sp that will calculate the number of working days ? I will have a start date only and need to calculate 20 working days from that date. TIA

TG
Master Smack Fu Yak Hacker

6065 Posts

Posted - 2005-03-07 : 13:15:23
search on "working days". There a several good posts discussing this. Most reasonable solutions involve keeping a permenant table that would hold all days and flag the holidays and work days for your culture. It's possible to do without that but the sql is MUCH easier with it.

Be One with the Optimizer
TG
Go to Top of Page

Pinto
Aged Yak Warrior

590 Posts

Posted - 2005-03-08 : 09:41:58
I found this example but I cannot paste it into a stored procedure. The syntax is ok but I get an error when I try to save it. Error 21001 Stored procedure definition must include name and text

CREATE FUNCTION fAddWorkingDay (@Start datetime, @NumOfDays integer)
RETURNS datetime
AS
BEGIN
DECLARE @NextDay datetime
DECLARE @Counter int

IF @NumOfDays>0
BEGIN
SET @Counter=1
-- Drop the time part and initialize the Return Variable

SET @NextDay=CONVERT(datetime ,(CONVERT(char(10),@Start,102)),102 )

WHILE @Counter <= @NumOfDays
BEGIN
SET @NextDay = dbo.fNextWorkingDay(@NextDay)
SET @Counter=@Counter+1
END
END
ELSE
BEGIN
SET @Counter=ABS(@NumOfDays)
-- Drop the time part and initialize the Return Variable

SET @NextDay=CONVERT(datetime ,(CONVERT(char(10),@Start,102)),102 )

WHILE @Counter>0
BEGIN
SET @NextDay = dbo.fPreviousWorkingDay(@NextDay)
SET @Counter=@Counter-1
END
END

RETURN @NextDay
END
Go to Top of Page

Xerxes
Aged Yak Warrior

666 Posts

Posted - 2005-03-08 : 09:45:08
It appears that you're attempting to turn a user-defined function into a stored procedure. Your error occurs because you're saying CREATE FUNCTION. Replace CREATE FUNCTION with CREATE PROCEDURE!

Semper fi,

XERXES, USMC(Ret.)
------------------------------------------------------
The Marine Corps taught me everything but SQL!
Go to Top of Page

Bustaz Kool
Master Smack Fu Yak Hacker

1834 Posts

Posted - 2005-03-08 : 18:28:35
You'll need to change the RETURN, also. You could pass @NextDay in as another parameter and mark it as an "OUTPUT" type.

HTH

=================================================================
In order to improve the mind, we ought less to learn than to contemplate.
-Rene Descartes, philosopher and mathematician (1596-1650)
Go to Top of Page

Xerxes
Aged Yak Warrior

666 Posts

Posted - 2005-03-09 : 09:37:48
quote:
Originally posted by Bustaz Kool

You'll need to change the RETURN, also. You could pass @NextDay in as another parameter and mark it as an "OUTPUT" type.

HTH

=================================================================
In order to improve the mind, we ought less to learn than to contemplate.
-Rene Descartes, philosopher and mathematician (1596-1650)




Great idea, Steve! Wish I'd thought of that!

Semper fi,

XERXES, USMC(Ret.)
------------------------------------------------------
The Marine Corps taught me everything but SQL!
Go to Top of Page

jsmith8858
Dr. Cross Join

7423 Posts

Posted - 2005-03-09 : 10:03:15
That function looks pretty bad -- I wouldn't use it. I'll post one in a few minutes for you. but, as mentioned, if you want to exclude holidays and such, you'll need a more sophisticated method and also a table of dates to exclude.

- Jeff
Go to Top of Page

jsmith8858
Dr. Cross Join

7423 Posts

Posted - 2005-03-09 : 10:10:22
this lets you go backwards and forwards. seems to work fine, and it has no loops. check it out.

Create function NextWorkDay(@CurrDate datetime, @DaysToAdd int)
returns datetime
as
begin
declare @WeeksToAdd int;
declare @dw int;

set @WeeksToAdd = (@DaysToAdd / 5) * 7
set @DaysToAdd = @DaysToAdd % 5

set @CurrDate = DateAdd(dd,@WeeksToAdd + @DaysToAdd, @CurrDate)
set @dw = datepart(dw,@CurrDate)

if sign(@DaysToAdd) < 0
begin
if @dw = 1 set @CurrDate = @CurrDate - 2
if @dw = 7 set @CurrDate = @CurrDate - 1
end
else
begin
if @dw = 1 set @CurrDate = @CurrDate + 1
if @dw = 7 set @CurrDate = @CurrDate + 2
end

return @CurrDAte
end

if you only need to go forward (i.e., DaysToAdd will always be positive) you can simplify that last IF condition.

Note: The function assumes that the starting date you specify will be a week day.

- Jeff
Go to Top of Page

bluecjh
Starting Member

7 Posts

Posted - 2005-03-11 : 07:08:43
functions to return 'working days' tend to fall into
2 categories, either set based using a calendar table which marks
weekends and public holidays
or a loop based approach examining each day and deciding if it is working day etc...

If you're looking for the nth working day then if n is large the set based approach is
quicker, if n is small a loop can be much quicker.

Chris
Go to Top of Page

Kristen
Test

22859 Posts

Posted - 2005-03-12 : 00:45:37
Can't you use a TALLY table to avoid the loop?

Kristen
Go to Top of Page

groston
Yak Posting Veteran

61 Posts

Posted - 2005-03-14 : 14:55:00
Here is a similar function that I just wrote. Note that the table Holiday contains a list of all business-specified holidays. This function returns true if @CurDate is within @DayNum business days of the beginning of the month.

ALTER FUNCTION dbo.udf_BusinessDayOfMonth
(
@CurDate datetime, -- must be passed in since UDF's cannot have getdate calls
@DayNum int -- check for which business day
)
RETURNS bit
AS
BEGIN
DECLARE @CurMonth int
DECLARE @CheckDay datetime
DECLARE @IsHoliday int
DECLARE @RetVal bit

SET @RetVal = 0
SET @CheckDay = @CurDate
SET @CurMonth = datepart (month, @CurDate)

WHILE @DayNum > 0
BEGIN
SET @CheckDay = dateadd (day, -1, @CheckDay)

if datepart (month, @CheckDay) <> @CurMonth
begin
SET @RetVal = 1
break
end
else
begin
SELECT @IsHoliday = count(*) FROM Holiday WHERE Holidate = @CheckDay

if not (@IsHoliday = 1 OR datepart (weekday, @CheckDay) = 1 OR datepart (weekday, @CheckDay) = 7)
SET @DayNum = @DayNum - 1
end
END

RETURN @RetVal
END
Go to Top of Page
   

- Advertisement -