Time Calc

J

Jonathan

I am trying to do a time calculation. Here is the scenario. A call comes in
at 4pm and there is a 4 hr turnaround time to respond, business hours. The
Work hrs are from 8am-6pm. I need to show the 2 hrs from day one and the
number of hours on day two. I have a [calltime] field and a [contacttime]
field. Also, we have to take into account if the call came in on Friday so
the remaining hrs should be reflected for Monday. Can anyone help me with
this?
 
G

gary b

I am trying to do a time calculation.  Here is the scenario.  A call comes in
at 4pm and there is a 4 hr turnaround time to respond, business hours.  The
Work hrs are from 8am-6pm.  I need to show the 2 hrs from day one and the
number of hours on day two.  I have a [calltime] field and a [contacttime]
field.  Also, we have to take into account if the call came in on Friday so
the remaining hrs should be reflected for Monday.  Can anyone help me with
this?

Jonathan...

Let me outline how I would approach this problem:
1. Take callfield time and subtract from 6PM (Ex: 1800 - 0930 =
0630)
2. If difference GREATER than 0400, then contacttime is TODAY!
3. If difference is LESS that 0400:
a. If TODAY not equal to Friday, make contacttime = tomorrow @ (0800 +
difference)
b.If TODAY equal to Friday, make contacttime = Monday @ (0800 +
difference)

Sample: Call received 1730 on Friday (5:30 PM on Friday)
Difference: 0030
Test 3a: does not apply
Test 3b: does apply. Therefore, contacttime is Monday @ 0830 (0800 +
difference) -- 8:30AM on Monday

This is just one approach.

You could test:
IF calltime < 1400 THEN
contacttime = TODAY @ calltime + 0400
ELSE
IF Today = Friday THEN
contacttime = Monday @ 0800 + difference
ELSE
contacttime = TOMORROW @ 0800 + difference
END IF
END IF

HTH

gb
 
J

James A. Fortune

Jonathan said:
I am trying to do a time calculation. Here is the scenario. A call comes in
at 4pm and there is a 4 hr turnaround time to respond, business hours. The
Work hrs are from 8am-6pm. I need to show the 2 hrs from day one and the
number of hours on day two. I have a [calltime] field and a [contacttime]
field. Also, we have to take into account if the call came in on Friday so
the remaining hrs should be reflected for Monday. Can anyone help me with
this?

That is a relatively general question that I will have to spend some
time thinking about. In the meantime, perhaps you can use my
TimeIntersection() function to restrict duration calculations to working
hours. Subtracting the duration of off hours from the total duration
should also work. Note that for either method the Date/Time fields must
include the date part.

A TimeIntersection() function can be found here:

http://groups.google.com/group/microsoft.public.access/msg/9ce7997df8677fca

C.f.:

http://groups.google.com/group/comp.databases.ms-access/msg/44ed54b162a1aa3c

Note: I now avoid using the internal representation of Date/Time fields
in calculations.

James A. Fortune
(e-mail address removed)
 
J

Jackie L

Jonathan,

I don't know if someone has a better suggestion but I am doing something
similar for machine scheduling.

First, create a table for the workday start and stop times. This is
information which could go directly into the query but I do not like to
program that way.
tblWorkDay
Fields: StartDay Date/Time Medium Time
EndDay Date/Time Medium Time
Create a qryTimeRemaining (where tblCallReceived is your data table and
field CallTime is the time the call came in) with the following statement:
SELECT tblCallReceived.CallTime, Format(DateAdd("h",4,[CallTime]),"medium
time") AS CallEnd, DateDiff("n",[EndDay],[CallEnd]) AS TimeRemaining,
Format(DateAdd("h",4,[CallTime]),"General Date") AS CallEndActual
FROM tblCallReceived, tblWorkDay;


Then create the query qryNewContactTime with the following statement:
SELECT qryTimeRemaining.TimeRemaining,
DateAdd("n",[TimeRemaining],[StartDay]) AS NewCallEndTime,
Format(IIf(Weekday([CallTime])=6,DateAdd("d",3,[CallTime]),DateAdd("d",1,[CallTime])),"Short
Date") AS CallEndDay, Format([CallEndDay] & " " & [NewCallEndTime],"General
Date") AS NewContactTime
FROM qryTimeRemaining, tblWorkDay
WHERE (((qryTimeRemaining.TimeRemaining)>0));

You will need to use the current record you are on as criteria in the
qryTimeRemaining

I don't know where you want the data to be added but if you put the
following code on the AfterUpdate event of your CallTime field you should be
good to go:

IF DMax("TimeRemaining","qryTimeRemaining)>0 then
Me.ContactTime = DateAdd("h",4,Me.CallTime)
Else
Me.ContactTime = DMax("NewContactTime","qryNewContactTime')
End IF

This might not be the most gracefull way to accomplish this but it does
work. If you need to take into account calls made on a Saturday, different
start and end times depending on the day of the week and holidays, then we
will have more to discuss...

Hope this helps,
Jackie
 
S

S.Clark

The answer is you'll need to write VBA code to determine the end time at the
'4 hour' mark. This will require multiple if or Select statements.

Things like
if StartTime > 2pm
'handle wrap to next day
if StartDay = Friday
'handle wrap to next week
end if
end if
 
M

Mr. B

Jonathan,

I am assuming that you have a field where you enter the time that the call
came in and another field where the time that contact was made is also
entered.

I am assuming that these fields are represented on a form and that both of
these fields are formatted as "Short Time". Data entry into these controls
would be made by entering 4:00 PM or 10:00 AM. When data is completed in one
control the value will be immediately converted to military time. If you
enter 4:00 PM the value dislayed when you leave the field will be 16:00.

With all of these things assumed, below is a function that will do the
calculations for you.

Function ElapsedTime(CallTime As Variant, ContactTime As Variant) As Variant
Dim varEndOfDay As Variant
Dim varStarOfDay As Variant
Dim varCallElpsTime As Variant
Dim varFirstDayElpsTime As Variant

varEndOfDay = #6:00:00 PM#
varStarOfDay = #8:00:00 AM#
'if the contact time is less than the time that the call came in
'then the call came in on the day before
If ContactTime < CallTime Then
varFirstDayElpsTime = DateDiff("n", CallTime, varEndOfDay) / 60
varCallElpsTime = DateDiff("n", varStarOfDay, ContactTime) / 60
ElapsedTime = varFirstDayElpsTime + varCallElpsTime
Else
'the call came in and contact was made on the same day
varCallElpsTime = DateDiff("n", CallTime, ContactTime) / 60
ElapsedTime = varCallElpsTime
End If
End Function

This function sets the start and ending of you day and then calculates the
elapsed time.

You would need to place the following code to call the function in the After
Update event of the "Call Time" text box and the "Contact Time" text box.

If Not IsNull(Me.txtCallTime) And _
Not IsNull(Me.txtContactTime) Then
Me.txtElapsedTime = ElapsedTime(Me.txtCallTime, Me.txtContactTime)
End If

Change the "txtCallTime" to the name of your "Call Time" text box and change
the "txtContactTime" to the name of your "Contact Time: text box. I have
also assumed that there would be a text box control for the elasped time,
formated as a
General number, locked and update by the function. Change the
"txtElapsedTime" to the name of this control.

Post back if you have problems. I have tested the code here but you will
have to implement it for your conditions. Also if you are planning to move
between records and have the elapsed time display for each existing record,
place the same code that you placed in the After Update event of the text box
control, in the On Current event of your form.

-----
HTH
Mr. B
http://www.askdoctoraccess.com/
Doctor Access Downloads Page:
http://www.askdoctoraccess.com/DownloadPage.htm


Jonathan said:
I am trying to do a time calculation. Here is the scenario. A call comes in
at 4pm and there is a 4 hr turnaround time to respond, business hours. The
Work hrs are from 8am-6pm. I need to show the 2 hrs from day one and the
number of hours on day two. I have a [calltime] field and a [contacttime]
field. Also, we have to take into account if the call came in on Friday so
the remaining hrs should be reflected for Monday. Can anyone help me with
this?
 
J

James A. Fortune

A response is given below the quoted sections.
Jonathan:

While James has got his thinking cap on let me have a stab at this:

First create a calendar table of all working days (Mon to Fri) by using the
following function:

Public Function MakeCalendar_DAO(strtable As String, _
dtmStart As Date, _
dtmEnd As Date, _
ParamArray varDays() As Variant)

' Accepts: Name of calendar table to be created: String.
' Start date for calendar: DateTime.
' End date for calendar: DateTime.
' Days of week to be included in calendar
' as value list, e,g 2,3,4,5,6 for Mon-Fri
' (use 0 to include all days of week)

Dim dbs As DAO.Database, tdf As DAO.TableDef
Dim strSQL As String
Dim dtmdate As Date
Dim varDay As Variant
Dim lngDayNum As Long

Set dbs = CurrentDb

' does table exist? If so get user confirmation to delete it
For Each tdf In dbs.TableDefs
If tdf.Name = strtable Then
If MsgBox("Replace existing table: " & _
strtable & "?", vbYesNo + vbQuestion, _
"Delete Table?") = vbYes Then
strSQL = "DROP TABLE " & strtable
dbs.Execute strSQL
Exit For
Else
Exit Function
End If
End If
Next tdf

' create new table
strSQL = "CREATE TABLE " & strtable & _
"(calDate DATETIME, " & _
"CONSTRAINT PrimaryKey PRIMARY KEY (calDate))"
dbs.Execute strSQL

' refresh database window
Application.RefreshDatabaseWindow

If varDays(0) = 0 Then
' fill table with all dates
For dtmdate = dtmStart To dtmEnd
lngDayNum = lngDayNum + 1
strSQL = "INSERT INTO " & strtable & "(calDate) " & _
"VALUES(#" & Format(dtmdate, "mm/dd/yyyy") & "#)"

dbs.Execute strSQL
Next dtmdate
Else
' fill table with dates of selected days of week only
For dtmdate = dtmStart To dtmEnd
For Each varDay In varDays()
If Weekday(dtmdate) = varDay Then
lngDayNum = lngDayNum + 1
strSQL = "INSERT INTO " & strtable & "(calDate) " & _
"VALUES(#" & Format(dtmdate, "mm/dd/yyyy") & "#)"
dbs.Execute strSQL
End If
Next varDay
Next dtmdate
End If

End Function

Call it like so to make a calendar table called WorkDaysCalendar for the next
10 years:

MakeCalendar_DAO "WorkDaysCalendar", #2009-01-01#,#2019-12-31#,2,3,4,5,6

As and when you know them delete any rows from the table for public or
concessionary holidays so these aren't counted as work days.

You can now create a function to return the response time in minutes:

Public Function ResponseTime(dtmCallReceived As Date, dtmResponded As Date)
As Long

Const IN_TIME = 600
Dim lngMinutes As Long
Dim dtmDateReceived As Date
Dim dtmDateResponded As Date

dtmDateReceived = DateValue(dtmCallReceived)
dtmDateResponded = DateValue(dtmResponded)

If dtmDateResponded = dtmDateReceived Then
' response on same day so simple time difference
lngMinutes = DateDiff("n", dtmCallReceived, dtmResponded)
Else
' resonse on later day so get minutes until 18:00 on day 1
lngMinutes = _
DateDiff("n", dtmCallReceived, DateAdd("h", 18, dtmDateReceived))
' add number of minutes in whole working days before response
lngMinutes = lngMinutes + _
DCount("*", "WorkDaysCalendar", "calDate > #" & _
Format(dtmDateReceived, "yyyy-mm-dd") & "# And " & _
"calDate < #" & Format(dtmDateResponded, "yyyy-mm-dd") & "#") *
IN_TIME
' add minutes after 8:00 on date of response
lngMinutes = lngMinutes + _
DateDiff("n", DateAdd("h", 8, dtmDateResponded), dtmResponded)
End If

ResponseTime = lngMinutes

End Function

The function can then be called like so:

ResponseTime(#2009-10-16 14:30#,#2009-10-19 17:40#)

which returns 790, the response time in minutes.

If you want to convert this to hours and minutes you can do so like this:

Dim lngResponseMinutes As Long
Dim strResponse As String

lngResponseMinutes = _
ResponseTime(#2009-10-16 14:30#,#2009-10-19 17:40#)

strResponse = lngResponseMinutes \ 60 & ":" & _
Format(lngResponseMinutes Mod 60, "00")

This will assign a value 13:10 to the strResponse variable. I've
deliberately used an unrealistically long response time here to illustrate it.
In fact the function should be able to cope with a response from virtually
instant to many days. You'd pass the call time and contact time into it
rather than literal date times of course. I'm assuming that these are
entered as full date/time values, not just as times.

I've tested the above with a few dates and times, and it seems to give the
right results, but you'll appreciate that it has been dashed off quickly so
should be thoroughly tested before being used.

The function could be made more generic by allowing the start and end times
for the working day to be passed into it as arguments as well as the call
time and contact time, in which case the IN_TIME could then be computed from
these times as a variable rather than a constant, and similarly variables
would be used in pace of the constants 8 and 18 when calling the DateAdd
function.

Ken Sheridan
Stafford, England
I am trying to do a time calculation. Here is the scenario. A call comes in
at 4pm and there is a 4 hr turnaround time to respond, business hours. The
Work hrs are from 8am-6pm. I need to show the 2 hrs from day one and the
number of hours on day two. I have a [calltime] field and a [contacttime]
field. Also, we have to take into account if the call came in on Friday so
the remaining hrs should be reflected for Monday. Can anyone help me with
this?

I've still got the cap on, figuratively speaking. BTW, I usually don't
wear a cap. Besides having a full head of hair, wearing a hat is
unbiblical! That comes from the Apostle Paul:

A) Men should not cover their heads while praying.

B) Pray without ceasing.

A & B => no cap :)

Ken's approach is the classical standard way that Enterprise SQL people
solve dealing with holidays or exclude regular daily time periods.
Actually, his solution is better than that because only a week of days
is generated. Explicitly creating tables containing all the
possibilities makes the criteria as simple as adding another JOIN and
gives total control over any kind of exceptions that can come up. I
don't want a solution that doesn't have such flexibility. Plus, the
separation of business logic (i.e., table vs. code) yields additional
benefits. Given the mostly predictable nature of holidays, I like using
algorithms to determine when they occur. There have been some notable
exceptions, such as holidays being declared by fiat to be moved to a
Monday or a Friday when they occur on Tuesday or Thursday, respectively.
My compromise in the past was to create algorithms for the holidays
and allow the developer to create code utilizing the algorithms or to
use the algorithms to create their holiday table. Personally, in some
situations, that took the form of hybrid code that would use the
algorithms to do computations such as counting holidays, yet allowed for
a table to catch unusual situations. That solution did not preserve the
independence of the business logic, but did avoid having to maintain a
holiday table. Having a table containing a recurring pattern for a
particular day, or maybe even a weekday and a weekend day, is much more
intellectually satisfying than generating a table with, say, ten years
of days. So the cap is still on, figuratively speaking. But maybe I
can come up with some intermediate solutions while pondering that mystery.

James A. Fortune
(e-mail address removed)

O Jesu vita Precantium -- Part of a song title from "Eternal Baroque"
album free download currently on http://www.amazon.com
 
J

Jonathan

Ken

This works Fantastic. I would like to display the "ResponseTime" in the
hour and minute format, ie 13:10 but I am not able to get it to work. Can
you help direct me on fixing this issue? My issue is that I don't know the
correct place to insert the following statements:

lngResponseMinutes = _
ResponseTime(#2009-10-16 14:30#,#2009-10-19 17:40#)

strResponse = lngResponseMinutes \ 60 & ":" & _
Format(lngResponseMinutes Mod 60, "00")

I used the formula as you stated below.
Thanks
Jonathan


--
Jonathan


KenSheridan via AccessMonster.com said:
Jonathan:

While James has got his thinking cap on let me have a stab at this:

First create a calendar table of all working days (Mon to Fri) by using the
following function:

Public Function MakeCalendar_DAO(strtable As String, _
dtmStart As Date, _
dtmEnd As Date, _
ParamArray varDays() As Variant)

' Accepts: Name of calendar table to be created: String.
' Start date for calendar: DateTime.
' End date for calendar: DateTime.
' Days of week to be included in calendar
' as value list, e,g 2,3,4,5,6 for Mon-Fri
' (use 0 to include all days of week)

Dim dbs As DAO.Database, tdf As DAO.TableDef
Dim strSQL As String
Dim dtmdate As Date
Dim varDay As Variant
Dim lngDayNum As Long

Set dbs = CurrentDb

' does table exist? If so get user confirmation to delete it
For Each tdf In dbs.TableDefs
If tdf.Name = strtable Then
If MsgBox("Replace existing table: " & _
strtable & "?", vbYesNo + vbQuestion, _
"Delete Table?") = vbYes Then
strSQL = "DROP TABLE " & strtable
dbs.Execute strSQL
Exit For
Else
Exit Function
End If
End If
Next tdf

' create new table
strSQL = "CREATE TABLE " & strtable & _
"(calDate DATETIME, " & _
"CONSTRAINT PrimaryKey PRIMARY KEY (calDate))"
dbs.Execute strSQL

' refresh database window
Application.RefreshDatabaseWindow

If varDays(0) = 0 Then
' fill table with all dates
For dtmdate = dtmStart To dtmEnd
lngDayNum = lngDayNum + 1
strSQL = "INSERT INTO " & strtable & "(calDate) " & _
"VALUES(#" & Format(dtmdate, "mm/dd/yyyy") & "#)"

dbs.Execute strSQL
Next dtmdate
Else
' fill table with dates of selected days of week only
For dtmdate = dtmStart To dtmEnd
For Each varDay In varDays()
If Weekday(dtmdate) = varDay Then
lngDayNum = lngDayNum + 1
strSQL = "INSERT INTO " & strtable & "(calDate) " & _
"VALUES(#" & Format(dtmdate, "mm/dd/yyyy") & "#)"
dbs.Execute strSQL
End If
Next varDay
Next dtmdate
End If

End Function

Call it like so to make a calendar table called WorkDaysCalendar for the next
10 years:

MakeCalendar_DAO "WorkDaysCalendar", #2009-01-01#,#2019-12-31#,2,3,4,5,6

As and when you know them delete any rows from the table for public or
concessionary holidays so these aren't counted as work days.

You can now create a function to return the response time in minutes:

Public Function ResponseTime(dtmCallReceived As Date, dtmResponded As Date)
As Long

Const IN_TIME = 600
Dim lngMinutes As Long
Dim dtmDateReceived As Date
Dim dtmDateResponded As Date

dtmDateReceived = DateValue(dtmCallReceived)
dtmDateResponded = DateValue(dtmResponded)

If dtmDateResponded = dtmDateReceived Then
' response on same day so simple time difference
lngMinutes = DateDiff("n", dtmCallReceived, dtmResponded)
Else
' resonse on later day so get minutes until 18:00 on day 1
lngMinutes = _
DateDiff("n", dtmCallReceived, DateAdd("h", 18, dtmDateReceived))
' add number of minutes in whole working days before response
lngMinutes = lngMinutes + _
DCount("*", "WorkDaysCalendar", "calDate > #" & _
Format(dtmDateReceived, "yyyy-mm-dd") & "# And " & _
"calDate < #" & Format(dtmDateResponded, "yyyy-mm-dd") & "#") *
IN_TIME
' add minutes after 8:00 on date of response
lngMinutes = lngMinutes + _
DateDiff("n", DateAdd("h", 8, dtmDateResponded), dtmResponded)
End If

ResponseTime = lngMinutes

End Function

The function can then be called like so:

ResponseTime(#2009-10-16 14:30#,#2009-10-19 17:40#)

which returns 790, the response time in minutes.

If you want to convert this to hours and minutes you can do so like this:

Dim lngResponseMinutes As Long
Dim strResponse As String

lngResponseMinutes = _
ResponseTime(#2009-10-16 14:30#,#2009-10-19 17:40#)

strResponse = lngResponseMinutes \ 60 & ":" & _
Format(lngResponseMinutes Mod 60, "00")

This will assign a value 13:10 to the strResponse variable. I've
deliberately used an unrealistically long response time here to illustrate it.
In fact the function should be able to cope with a response from virtually
instant to many days. You'd pass the call time and contact time into it
rather than literal date times of course. I'm assuming that these are
entered as full date/time values, not just as times.

I've tested the above with a few dates and times, and it seems to give the
right results, but you'll appreciate that it has been dashed off quickly so
should be thoroughly tested before being used.

The function could be made more generic by allowing the start and end times
for the working day to be passed into it as arguments as well as the call
time and contact time, in which case the IN_TIME could then be computed from
these times as a variable rather than a constant, and similarly variables
would be used in pace of the constants 8 and 18 when calling the DateAdd
function.

Ken Sheridan
Stafford, England
I am trying to do a time calculation. Here is the scenario. A call comes in
at 4pm and there is a 4 hr turnaround time to respond, business hours. The
Work hrs are from 8am-6pm. I need to show the 2 hrs from day one and the
number of hours on day two. I have a [calltime] field and a [contacttime]
field. Also, we have to take into account if the call came in on Friday so
the remaining hrs should be reflected for Monday. Can anyone help me with
this?

--
Message posted via AccessMonster.com


.
 
J

James A. Fortune

KenSheridan said:
But wait and see what James comes up with. It will doubtless be something
whose elegance and efficiency knocks your socks off. Unlike me, he's a real
pro at this sort of thing.

Ken Sheridan
Stafford, England

Don't try that. I dubbed you the pro so that the burden stays on you! :)

James A. Fortune
(e-mail address removed)
 
J

James A. Fortune

Jonathan said:
Ken

This works Fantastic.

Since the need is not exigent, I will take my time thinking about that
problem. My objection with a 10 years of days table is purely
aesthetic, rather than over efficiency concerns. A join on such a table
should be quite efficient and maintain business rule independence.

James A. Fortune
(e-mail address removed)

I'm forced to buy at least the minimum car insurance. If I get a ticket
or am at fault in an accident, my rates go up for awhile. If that
happens and I want to drive, I have no choice but to pay the increased
rates. If I must have health insurance, either through purchasing it or
by it being provided by my employer, then if I have any habits that are
deemed unhealthy or have an "accident," those rates will also go up.
That amounts to a potential lifestyle fee or tax. I lead a healthy
lifestyle, so I'm not really afraid of that (unless, God forbid, I get
struck by catastrophe), but I think that many will not like the changes
that will be brought about by the proposed healthcare system in the U.S.
in terms of lifestyle punishment. Even with the current car insurance
rules, if you do not already have medical coverage, you must pay extra
car insurance to cover medical risks. That's not all bad, but it still
imposes a penalty system for mistakes. The insurance companies lobbied
hard for mandatory health insurance coverage on the basis of "fairness."
I think fair would be a system where I get to charge my congressperson
or insurance agency a fee whenever THEY make a what I deem to be a mistake.
 
J

Jonathan

Ken/James

Thank you for your input and advise. All of this has helped to alleviate a
lot of stress and time that I have spent trying to get the same result.

Thanks once again
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top