13,192,855 members (53,893 online)
alternative version

#### Stats

44.1K views
16 bookmarked
Posted 11 Jul 2007

, 11 Jul 2007
 Rate this:
An article on how to calculate business hours between two dates

## Introduction

I was recently asked how many business hours/minutes are between two given dates. I thought the work of finding out would not be so heavy, but it was. In this sample application, I will calculate it with a hard-coded working day range from 8 am. to 5 pm. Holidays are not observed yet.

## How many days are between these dates?

```int GetBusinessDays(CTime ctStart, CTime ctEnd)
{
CTimeSpan ctp(ctEnd - ctStart);
int iDays = ctp.GetDays() + 1;
int iWeeks = iDays / 7;
int iBusDays = iWeeks * 5;
int iRem = iDays % 7;
while (iRem > 0)
{ // no sunday, no saturday
if ((ctStart.GetDayOfWeek() != 1) && (ctStart.GetDayOfWeek() != 7))
{
iBusDays++;
}          ctStart += CTimeSpan(1,0,0,0); // add a day
iRem--;
}
return iBusDays;
} ```

Ok, so far so good. Now that we have the number of working days, let us calculate the hours.

## The first and last day in the date range are "special" days

We can calculate each day with 9 hours per day (predefined range), but not the first and the last day. Let's start calculating seconds for the first day:

```DWORD CorrectFirstDayTime(CTime ctStart, CTime ctMaxTime, CTime ctMinTime)
{
DWORD daysec = 0;

if (ctMaxTime < ctStart) // start time is after max time
return 0; // zero seconds for the first day

if ((ctStart.GetDayOfWeek() == 1) || (ctStart.GetDayOfWeek() == 7))
return 0;             // zero seconds      for weekend

if (ctStart < ctMinTime) // start time is befor min time
ctStart = ctMinTime; // set start time to min time

// calulate seconds of this day
CTimeSpan ctSpan(ctMaxTime - ctStart);
daysec =
(ctSpan.GetDays() * 24 * 60 * 60) + (ctSpan.GetHours() * 60 * 60) +
(ctSpan.GetMinutes() * 60) + ctSpan.GetSeconds();

return daysec;
}```

Ok, now the same with the last day:

```DWORD CorrectLastDayTime(CTime ctEnd, CTime ctMaxTime, CTime ctMinTime)
{
DWORD daysec = 0;

if (ctMinTime > ctEnd) // end time is befor min time
return 0; // zero seconds for the end day

if ((ctEnd.GetDayOfWeek() == 1) || (ctEnd.GetDayOfWeek() == 7))
return 0;

if (ctEnd > ctMaxTime) // end time is afer max time
ctEnd = ctMaxTime;  // set end time to max time

// calulate seconds of this day
CTimeSpan ctSpan(ctEnd - ctMinTime);
daysec =
(ctSpan.GetDays() * 24 *   60  * 60) + (ctSpan.GetHours() * 60 * 60) +
(ctSpan.GetMinutes() * 60) + ctSpan.GetSeconds();

return daysec;
}```

## All together now

Ready. Now we have all of the time values we need. If we put all this together, we get a function with three parameters.

• Parameter 1: `dtStart` is our start date and time value, e.g. 06/20/2007 06:00:00 am
• Parameter 2: `dtEnd` is our end date and time value, e.g. 07/14/2007 05:00:00 pm
• Parameter 3: `bIsUTCTime` is set to TRUE when Parameters 1 and 2 are UTC time values
```double CalculateBusinessMinutes(CTime dtStart, CTime dtEnd, BOOL bIsUTCTime)
{
// initialze our return value
double OverAllMinutes = 0.0;

// start time must be less than end time
if (dtStart > dtEnd)
return OverAllMinutes;

if (bIsUTCTime)
{
// convert time from UTC to local time
SYSTEMTIME ttStart;
SYSTEMTIME ttEnd;
SYSTEMTIME ttStartLocal;
SYSTEMTIME ttEndLocal;
dtStart.GetAsSystemTime(ttStart);
dtEnd.GetAsSystemTime(ttEnd);
SystemTimeToTzSpecificLocalTime(NULL, &ttStart, &ttStartLocal);
SystemTimeToTzSpecificLocalTime(NULL, &ttEnd, &ttEndLocal);
dtStart = ttStartLocal;
dtEnd = ttEndLocal;
}

// initialize our temp times with midnight values
CTime ctTempStart(dtStart.GetYear(),
dtStart.GetMonth(), dtStart.GetDay(), 0, 0, 0);
CTime ctTempEnd(dtEnd.GetYear(),
dtEnd.GetMonth(), dtEnd.GetDay(), 0, 0, 0);

// check if startdate and enddate are the same day
BOOL bSameDay = (ctTempStart == ctTempEnd);

// calculate the business days between the dates

// now add the time values to our temp times
ctTempStart += CTimeSpan(0, dtStart.GetHour(), dtStart.GetMinute(), 0);
ctTempEnd += CTimeSpan(0, dtEnd.GetHour(), dtEnd.GetMinute(), 0);

// set our workingday time range and correct the first day
CTime ctMaxTime(ctTempStart.GetYear(),
ctTempStart.GetMonth(), ctTempStart.GetDay(), 17, 0, 0);
CTime ctMinTime(ctTempStart.GetYear(),
ctTempStart.GetMonth(), ctTempStart.GetDay(), 8, 0, 0);
DWORD FirstDaySec =
CorrectFirstDayTime(ctTempStart, ctMaxTime, ctMinTime);

// set our workingday time range and correct the last day

CTime ctMaxTime1(ctTempEnd.GetYear(),
ctTempEnd.GetMonth(), ctTempEnd.GetDay(), 17, 0, 0);
CTime ctMinTime1(ctTempEnd.GetYear(),
ctTempEnd.GetMonth(), ctTempEnd.GetDay(), 8, 0, 0);
DWORD LastDaySec = CorrectLastDayTime(ctTempEnd, ctMaxTime1, ctMinTime1);
DWORD OverAllSec = 0;

// now sum-up all values
if (bSameDay)
{
{
CTimeSpan cts(ctMaxTime - ctMinTime);
(cts.GetDays() * 24 * 60 * 60) + (cts.GetHours() * 60 * 60) +
(cts.GetMinutes() * 60) + cts.GetSeconds();
OverAllSec = FirstDaySec + LastDaySec - dwBusinessDaySeconds;
}
}
else
{
OverAllSec =
((iBusinessDays - 2) * 9 * 60 * 60) + FirstDaySec + LastDaySec;
}
OverAllMinutes = OverAllSec / 60;

return OverAllMinutes;
}```

That's it! I hope you'll find it useful. Please let me know about bugs and other problems if you find any. Enjoy!

## Implementation notes

To implement this function into your application, add it and include the following files with your project:

The sample project was compiled under VS6 and has been tested on Windows XP. It will not work with versions earlier than Windows NT Workstation 3.5.

## Usage

This software is released into the public domain. You are free to use it in any way you like, except that you may not sell this source code. If you modify it or extend it, please consider posting the new code here for everyone to share. This software is provided "as is" with no expressed or implied warranty. I accept no liability for any damage or loss of business that this software may cause.

## History

• Version 1.0: 07/11/2007 - Initial release

A list of licenses authors might use can be found here

## Share

 Systems Engineer Germany
Ralph started programming in Turbo Pascal, later in Delphi. After this, he began learning C++, which is his favorite language up to now.

He is interested in almost everything that has to do with computing, his special interests are security and networking.

## You may also be interested in...

 First Prev Next
 Thanks Gaurav Dudeja India22-Sep-09 23:10 Gaurav Dudeja India 22-Sep-09 23:10
 Great Article, Thanks a lot....
 all depends... toxcct11-Jul-07 4:42 toxcct 11-Jul-07 4:42
 Re: all depends... perle111-Jul-07 4:51 perle1 11-Jul-07 4:51
 Re: all depends... toxcct11-Jul-07 4:55 toxcct 11-Jul-07 4:55
 Re: all depends... perle111-Jul-07 5:02 perle1 11-Jul-07 5:02
 Re: all depends... toxcct11-Jul-07 5:05 toxcct 11-Jul-07 5:05
 Re: all depends... MrGoodly11-Jul-07 6:29 MrGoodly 11-Jul-07 6:29
 Re: all depends... toxcct11-Jul-07 6:44 toxcct 11-Jul-07 6:44
 Last Visit: 31-Dec-99 18:00     Last Update: 18-Oct-17 5:31 Refresh 1