Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations SkipVought on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

How do I convert time from text to show business hours and calculate averages

Status
Not open for further replies.

LMGroup

MIS
Apr 10, 2006
85
0
0
CA
I'm using CR 2008 with an ODBC connection to a db on SQL Server 2005. The following code does almost everything that I need. I also need to be able to calculate the average response time. I'm not sure what to use or how to convert it to what I need. My times are based on a 9 hour business day. Weekends, holidays, and non-business hours are removed. The ToText result that is displayed shows the number of days, but these are 9 hour days, not 24. CR won't let me summarize the field. Any help would be greatly appreciated.

Code:
whileprintingrecords;

datetimevar createdate:={Cases.Case_CreatedDate};
numbervar createyear:=datepart("yyyy", {Cases.Case_CreatedDate});
numbervar createmonth:=datepart("m", {Cases.Case_CreatedDate});
numbervar createday:=datepart("d", {Cases.Case_CreatedDate});
numbervar createdayofweek:=dayofweek({Cases.Case_CreatedDate});
datevar createdateonly;

datetimevar respondate:={CaseProgress.Case_TimeStamp};
numbervar respondyear:=datepart("yyyy", {CaseProgress.Case_TimeStamp});
numbervar respondmonth:=datepart("m", {CaseProgress.Case_TimeStamp});
numbervar responday:=datepart("d", {CaseProgress.Case_TimeStamp});
numbervar respondayofweek:=dayofweek({CaseProgress.Case_TimeStamp});
datevar respondateonly;

numbervar secadjust:=0; //if interval spans a weekend(s) or evenings then time is removed
numbervar daydiff:=0;  //number of days between create and respond
numbervar respondtime;
numbervar Days; 
numbervar Hours; 
numbervar Minutes; 
numbervar Seconds;
shared numbervar respondflag;  //reset at the case group header level
numbervar i:=1;    //for looping through the Holidays
numbervar Hol:=0;
DateVar Array Holidays;

If {CaseProgress.Case_Stage}="Responded" and respondflag=0 then
   (

    if createdayofweek = 7 then     //if Saturday, make Monday 8am
        (createdate:=dateadd("d",2,createdate);
        createyear:=datepart("yyyy", createdate);
        createmonth:=datepart("m", createdate);
        createday:=datepart("d", createdate);
        createdate := cdatetime(createyear,createmonth,createday,8,00,00);)
    else if createdayofweek = 1 then     //if Sunday, make Monday 8am
        (createdate:=dateadd("d",1,createdate);
        createyear:=datepart("yyyy", createdate);
        createmonth:=datepart("m", createdate);
        createday:=datepart("d", createdate);
        createdate := cdatetime(createyear,createmonth,createday,8,00,00);)
    else if createdayofweek = 6 and time(createdate) > time(16,59,59) then  //if Friday after 5pm, make Monday 8am
        (createdate:=dateadd("d",3,createdate);
        createyear:=datepart("yyyy", createdate);
        createmonth:=datepart("m", createdate);
        createday:=datepart("d", createdate);
        createdate := cdatetime(createyear,createmonth,createday,8,00,00);)
    else if time(createdate) > time(16,59,59) then //if after 5pm, make next day 8am
        (createdate:=dateadd("d",1,createdate);
        createyear:=datepart("yyyy", createdate);
        createmonth:=datepart("m", createdate);
        createday:=datepart("d", createdate);
        createdate := cdatetime(createyear,createmonth,createday,8,00,00);)
    else if time(createdate) < time(8,00,00) then  //if before 8am, make 8am
        createdate := cdatetime(createyear,createmonth,createday,8,00,00);

    createdateonly := Date(createdate);

    if respondayofweek = 7 then     //if Saturday, make Monday 8am
        (respondate:=dateadd("d",2,respondate);
        respondyear:=datepart("yyyy", respondate);
        respondmonth:=datepart("m", respondate);
        responday:=datepart("d", respondate);
        respondate := cdatetime(respondyear,respondmonth,responday,8,00,01);)
    else if respondayofweek = 1 then     //if Sunday, make Monday 8am
        (respondate:=dateadd("d",1,respondate);
        respondyear:=datepart("yyyy", respondate);
        respondmonth:=datepart("m", respondate);
        responday:=datepart("d", respondate);
        respondate := cdatetime(respondyear,respondmonth,responday,8,00,01);)
    else if respondayofweek = 6 and time(respondate) > time(16,59,59) then  //if Friday after 5pm, make Monday 8am
        (respondate:=dateadd("d",3,respondate);
        respondyear:=datepart("yyyy", respondate);
        respondmonth:=datepart("m", respondate);
        responday:=datepart("d", respondate);       
        respondate := cdatetime(respondyear,respondmonth,responday,8,00,01);)
    else if time(respondate) > time(16,59,59) then //if after 5pm, make next day 8am
        (respondate:=dateadd("d",1,respondate);
        respondyear:=datepart("yyyy", respondate);
        respondmonth:=datepart("m", respondate);
        responday:=datepart("d", respondate);
        respondate := cdatetime(respondyear,respondmonth,responday,8,00,01);)
    else if time(respondate) < time(8,00,00) then  //if before 8am, make 8am
        respondate := cdatetime(respondyear,respondmonth,responday,8,00,01);

    respondateonly := Date(respondate);

    For i := 1 to Count(Holidays) Do
        (
        if createdateonly = Holidays[i] then
            createdate:=dateadd("d",1,createdate);
        if respondateonly = Holidays[i] then
            respondate:=dateadd("d",1,respondate);
        if Holidays[i] > createdateonly and Holidays[i] < respondateonly then
            Hol := Hol +1;
        );

    createdateonly := Date(createdate);
    respondateonly := Date(respondate);

    daydiff := DateDiff("d", createdate, respondate);

    if daydiff >= 1 then  //remove the number of seconds of nonbusiness hour time
        (if DateDiff("ww",createdate, respondate) <> 0 then  
            (daydiff := daydiff - (3*DateDiff("ww",createdate, respondate)); //remove 3 days for every weekend
            secadjust := 226800 * DateDiff("ww",createdate, respondate)); //add weekend seconds (63 hrs)
        secadjust := secadjust + (54000 * daydiff) + (32400 * Hol)); //add non-business hr seconds (15 hrs) and holiday seconds (9 hrs)

    respondtime:=DateDiff("s", createdate, respondate)-secadjust;
    respondflag:=1;

    Days    := Truncate  (respondtime / 32400);     //9 hr business day
    Hours   := Truncate  (Remainder ( respondtime , 32400) / 3600) ; 
    Minutes := Truncate  (Remainder ( respondtime , 3600) / 60) ; 
    Seconds := Remainder (respondtime , 60) ;

    Totext ( Days ,    '##' ) +  ':' + 
    Totext ( Hours ,   '00' ) +  ':' + 
    Totext ( Minutes , '00' ) +  ':' + 
    Totext ( Seconds , '00' ) 
    )
 
hi,

Please post an example of the date/time values that you have to work with and also post the expected result for each example.

Skip,
[sub]
[glasses]Just traded in my old subtlety...
for a NUANCE![tongue][/sub]
 
The code only calculates the time for the first record of each case. What I need is an average of all the times in the last column. The numbers are calculating correctly. 8/31 & 9/01 were weekend days and 9/02 is a holiday. Business hours are 8am-5pm, M-F.

Code:
	     Reference Id	        Created	                Responded	      # Business Days:Hrs:Min:Sec

	120 54295	8/30/2013   2:30:00PM	9/3/2013  10:08:57AM	 0:04:38:57
	120 54295	8/30/2013   2:30:00PM	9/6/2013   9:56:57AM

	120 54302	8/30/2013   4:03:00PM	9/4/2013   4:03:04PM	 2:00:00:04
	120 54302	8/30/2013   4:03:00PM	9/4/2013   3:54:25PM

	1 54278	        8/30/2013  10:11:00AM	9/3/2013  10:08:32AM	 0:08:57:32
	1 54278         8/30/2013  10:11:00AM	9/3/2013  12:32:51PM

	1 54279	        8/30/2013  10:16:00AM	8/30/2013   2:26:52PM	 0:04:10:52

	1 54280	        8/30/2013  10:16:00AM	9/10/2013   4:00:23PM	 6:05:44:23

	1 54283	        8/30/2013  10:46:00AM	9/3/2013   3:16:49PM	 1:04:30:49
	1 54283	        8/30/2013  10:46:00AM	9/3/2013   3:52:02PM

	1 54284	        8/30/2013  11:31:00AM	8/30/2013   1:17:00PM	 0:01:46:00
	1 54284	        8/30/2013  11:31:00AM	9/3/2013   4:00:22PM

	1 54288	        8/30/2013  11:56:00AM	8/30/2013  12:57:32PM	 0:01:01:32
	1 54288	        8/30/2013  11:56:00AM	8/30/2013   1:29:21PM

	1 54290	        8/30/2013  12:46:00PM	9/3/2013   3:15:30PM	 1:02:29:30
	1 54290	        8/30/2013  12:46:00PM	9/3/2013   3:15:38PM
	1 54290	        8/30/2013  12:46:00PM	9/4/2013  12:11:04PM

	1 54292	        8/30/2013   2:22:00PM	9/3/2013   9:59:50AM	 0:04:37:50

	1 54295	        8/30/2013   2:42:00PM	9/4/2013   5:21:55PM	 2:02:18:01
	1 54295	        8/30/2013   2:42:00PM	8/30/2013   3:08:58PM
	1 54295	        8/30/2013   2:42:00PM	8/30/2013   4:04:49PM

	1 54298	        8/30/2013   3:07:00PM	9/3/2013  10:00:10AM	 0:03:53:10

	1 54303	        8/30/2013   4:22:00PM	9/4/2013   8:44:35AM	 1:01:22:35

	1 54305	        8/30/2013  11:04:00PM	9/6/2013   2:54:38PM	 3:06:54:38

	1 54313	        8/31/2013  11:49:00PM	9/3/2013   9:34:32AM	 0:01:34:32
	1 54313	        8/31/2013  11:49:00PM	9/3/2013   2:19:20PM

	1 54325	        9/2/2013   6:49:00PM	9/4/2013  10:04:21AM	 1:02:04:21
 
The rub, IMNSHO, is to determine the a workday. My company has a manufacturing calendar, so it makes it a smap to determine whether a date is a workday.

But here's some simple code for calculating business hours based on workdays. You need actual date/time values, NOT strings! This code worked on your first example row, taking into account Labor Day.

Adapt to CR, as this is VBA.
Use Start & End date/time values.
i is a loop counter that goes from the STart date ot the ENd date
stFR & enFR are the FRACTIONAL values of the Date/Time value representing TIME.
The Constants are to identify the start and end times of the day and the hours in a full working day.
BTW, all these values are normalized to DAYS, the units of Date/Time values.

Code:
Function BusinessHours(ST, EN) As Single
    Dim i As Long, stFR As Single, enFR As Single

    Const DayST = 8 / 24
    Const DayEN = 17 / 24
    Const DayALL = 9 / 24

    stFR = ST - Int(ST)
    enFR = EN - Int(EN)

    For i = Int(ST) To Int(EN)
        If i = WorkDay Then
            If i = Int(ST) And stFR >= DayST And stFR < DayEN Then
'[b]this calculates the hours at the BEGINNING of the period  [/b]   
                BusinessHours = BusinessHours + DayEN - stFR
            
            ElseIf i = Int(EN) And enFR >= DayST And enFR < DayEN Then
'[b]this calculates the hours at the END of the period  [/b]   
                BusinessHours = BusinessHours + enFR - DayST
            
            Else
'[b]this calculates the hours DURING of the period  [/b]   
                BusinessHours = BusinessHours + DayALL
            
            End If
        
        End If
    Next
End Function

Skip,
[sub]
[glasses]Just traded in my old subtlety...
for a NUANCE![tongue][/sub]
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top