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)
 Calculating working hours between 2 datetimes

Author  Topic 

Bex
Aged Yak Warrior

580 Posts

Posted - 2005-10-13 : 07:18:43
Hello all

Right, I have an issue, and I am trying to work it out, but cannot see the woods for the trees. Therefore, I am hoping that some new eyes can shed some light on the problem:

The Requirement

Count the number of incoming mail that completed a process within a specified time for SLA purposes (an example would be when a mail batch was scanned and indexed)
I have a start_time and an end_time of when each process has completed
I have to calculate the working hours (down to the nearest millisecond) it took to complete the process from start to finish
The working hours differ per process

So far
I have a table containing the working hours for each process (as example of data is below):

StartTime                EndTime                   Process                   
----------------------- ------------------------ -----------------------
1900-01-01 09:00:00.000 1900-01-01 17:00:00.000 Email and Faxing
1900-01-01 07:30:00.000 1900-01-01 17:00:00.000 Scanning and Indexing


I created a function to caclulate the number of working hours per day (returning a date)
ALTER FUNCTION fn_LengthOfWorkingDay
(
@process VARCHAR(25)
)
RETURNS DATETIME
AS
BEGIN
DECLARE @returnDate DATETIME
SELECT @returnDate = EndTime - StartTime FROM WorkingDayHours WHERE Process = @process
RETURN @returnDate
END


For scanning and indexing it returns:
1900-01-01 09:30:00.000


My problem is that I need to calculate the number of working hours that have occurred between the start_time and the end_time of a process. I wrote a function to return the difference (one in milliseconds and another in a datetime format):


Returns a date
CREATE FUNCTION fn_CalculateDateDifference
(
@startDate DATETIME
, @endDate DATETIME
)
RETURNS DATETIME
AS
BEGIN
DECLARE @returnDate DATETIME
SELECT @returnDate = @endDate - @startDate
RETURN @returnDate
END


Returns number of milliseconds:
CREATE FUNCTION fn_CalculateMSBetweenDates
(
@startDate DATETIME
, @endDate DATETIME
)
RETURNS INT
AS
BEGIN
DECLARE @milliseconds INT
SELECT @milliseconds = (SELECT DATEDIFF(MS,@startDate, @endDate))
RETURN @milliseconds
END


However, neither of these account for weekends or the fact that these are total times and not 'working hours'. How can I calulate the number of working hours that have occured between the start and end times of the process, taking into account weekends????

Some sample data of start and end times for scanning and indexing are below:

rls_end_time              Scan Start time           Time Difference                                        
------------------------ ------------------------- ------------------------
2005-09-08 09:50:50.000 2005-09-08 09:44:51.000 1900-01-01 00:05:59.000
2005-09-13 15:38:59.000 2005-09-09 09:52:53.000 1900-01-05 05:46:06.000
2005-09-09 11:13:29.000 2005-09-09 10:51:13.000 1900-01-01 00:22:16.000
2005-09-14 10:53:44.000 2005-09-13 07:58:02.000 1900-01-02 02:55:42.000


So although I know the difference in time between the two dates, can i write a function that calculates the total amount of that time is actually 'working hours'. Would it be best to calculate in date format or determine or milliseconds?

God, I know this sounds so muddled, and the answer may be super simple, but my brain is all mixed up so pleeeeeeease, someone offer me some clarity or a new way of thinking!

Thanks in advance

Hearty head pats

Bex
Aged Yak Warrior

580 Posts

Posted - 2005-10-13 : 07:53:30
Ok, I have thought of something and would appreciate an opinion. Apologies if this is unclear a I am having a brainstorm:

· First of all, calculate the number of full days that have passed between the two dates

· (I do not know a function that can count a the number of days that have lapsed between a date range)

· Calculate the working hours for a specific process by querying the process table and times by the number of full days that have lapsed.

· For example, to work out the number of milliseconds that have passed for 2 full days for Scanning and Indexing, then
(SELECT (DATEDIFF (ms, <workday_starttime>, < workday_endtime>) X 2) FROM WorkingDayHours WHERE Process = ‘Scanning and Indexing’

· Calculate the time lapsed between the start_time and the end of the working day. For example,
(DATEDIFF(ms, < process_start_time >,< workday_endtime >))

· Do the same to work out the time passed during the last day (DATEDIFF(ms, < workday_starttime >,< process_end_time >))

· Add all the results together to obtain the complete working time that has lapsed.
· If any of the full days fall on a weekend, then do not include them in the total.

Right, now, although I have worked out some logic (whether it is correct I don’t know), but I have no idea how to implement it – For example, Is there a function to return the count of days that occur between a date range??

Anyway, your opinions are greatly appreciated!


Hearty head pats
Go to Top of Page

Bex
Aged Yak Warrior

580 Posts

Posted - 2005-10-13 : 08:04:59
Apologies for being a spaz, of course I know a function to count number of days between a date range - flipping DATEDIFF - oh my god, I hve been working on this for too long!

However, I still want advice!

Hearty head pats
Go to Top of Page

madhivanan
Premature Yak Congratulator

22864 Posts

Posted - 2005-10-13 : 09:04:47
>>Is there a function to return the count of days that occur between a date range??

Is this?

Select DateDiff(day,Date1,Date2) from yourTable

Madhivanan

Failing to plan is Planning to fail
Go to Top of Page

Bex
Aged Yak Warrior

580 Posts

Posted - 2005-10-13 : 10:02:04
Yeah, I know (see the email above yours)! Told you I was muddled! Doh!

Hearty head pats
Go to Top of Page

Bex
Aged Yak Warrior

580 Posts

Posted - 2005-10-13 : 13:08:07
For anyone who is interested, here is the solution (after much brain ache):

CREATE FUNCTION fn_CalculateWorkingHours
(
@startDate DATETIME
, @endDate DATETIME
, @process VARCHAR(25)
)
RETURNS BIGINT
AS
BEGIN
DECLARE @milliseconds BIGINT
DECLARE @numOfFullDays TINYINT
DECLARE @timePortion DATETIME

SET @numOfFullDays = 0

IF (DATEDIFF(DAY,@startDate,@endDate) > 0)
BEGIN

--Calculate the time lapsed between the start of the process to the end of the working day
SELECT @timePortion = @startDate - CAST(FLOOR(CAST(@startDate AS FLOAT))AS SMALLDATETIME)
SELECT @milliseconds = DATEDIFF(ms,@timePortion, WorkingDayHours.EndTime) FROM WorkingDayHours

--Calculate the time lapsed between the start of the working day and the end of the process
SELECT @timePortion = @endDate - CAST(FLOOR(CAST(@endDate AS FLOAT))AS SMALLDATETIME)
SELECT @milliseconds = @milliseconds + DATEDIFF(ms, WorkingDayHours.StartTime, @timePortion)
FROM WorkingDayHours
WHERE Process = @process

--Add a day onto the start date as you do not want to include the first day in the full working day count
SELECT @startDate = DATEADD(DAY,1,@startDate)

--Eradicate the time portion of the dates
SELECT @startDate = CAST(FLOOR(CAST(@startDate AS FLOAT))AS SMALLDATETIME)
SELECT @endDate = CAST(FLOOR(CAST(@endDate AS FLOAT))AS SMALLDATETIME)

--Calculate the number of full working days that have lapsed between the start and end date of the process
--As long as the day is less then (not <=) the last day date will not be included in the full working day count
WHILE @startDate < @endDate
BEGIN
--If the date is not included in the dates held in the BankHoliday Table, then it can be included in the count
IF NOT EXISTS(SELECT BankHolidayDate FROM BankHoliday WHERE BankHolidayDate = @startDate)
BEGIN
--If the day falls on a weekend, then it is not included in the count
SELECT @numOfFullDays = @numOfFullDays +
(CASE DATENAME(DAY,@startDate)
WHEN 'Saturday' THEN 0
WHEN 'Sunday' THEN 0
ELSE 1
END)
END
SELECT @startDate = DATEADD(DAY, 1, @startDate)

END

--Add the number of milliseconds for the working days to the total
SELECT @milliseconds = @milliseconds + (@numOfFullDays * dbo.fn_CalculateMSBetweenDates(StartTime, EndTime))
FROM WorkingDayHours WHERE Process = @process
END
ELSE
BEGIN
SELECT @milliseconds = DATEDIFF(MS,@startDate,@endDate)
END

RETURN (@milliseconds)
END



Hearty head pats
Go to Top of Page
   

- Advertisement -