You are here:

# C++/C++ program help

Question
QUESTION: #include <iostream>
#include <fstream>
#include <iomanip>
#include <cmath>
#include <time.h>

using namespace std;

int main()
{
// = (num3&&num4) - (num1&&num2);
// save this calc for later: hrIn + (hrOut/60.0);
// same thing = num3 + (num4/60);
// write an alogorithm to establish the steps to take to solve the problem
//(1) Declare some variables to work with
char fare;
char choice = 'y';
int hrIn, minIn, hrOut, minOut;
float hours;
float minutes;
float total_minutes;
double cost;
double arrive;
double depart;
float charge;

while (choice == 'y')
{
//(2) OUtput reqd info and user message

cout << "This program will calculate a single, couple, or group "
<< "
fare amount which is then owed by the customer for the trip.
"
<< "
To calculate a single fare amount, input S (or s)"
<< "
To calculate a couple fare amount, input C (or c)"
<< "
To calculate a group fare amount, input G (or g)"
<< "

Input S, C, or G: ";
cin >> fare;

if(fare=='S'||fare=='s')
{
cout << "
What hour did they depart? ";
cin >> hrIn;
cout << "
What minute did they depart? ";
cin >> minIn;
cout << "
You entered for departure: " << hrIn << ":" << minIn << endl;
cout << "
What hour did they arrive? ";
cin >> hrOut;
cout << "
What minute did they arrive? ";
cin >> minOut;
cout << "
You entered for arrival: " << hrOut << ":" << minOut << "
" << endl;
cout << "A rickshaw departed at " << hrIn << ":" << minIn
<< " and arrived at " << hrOut << ":" << minOut << " with a single customer.
" << endl;

float hours = hrOut - hrIn;
cout << "You arrived in " << hours << " hour(s)";
float minutes = minOut - minIn;
cout << " and " << minutes << " minute(s)";
float total_minutes = (hours * 60) + minutes;
cout << ", or in " << total_minutes << " minutes.
" << endl;

if(total_minutes <= 30.0)
{
cout << fixed << showpoint << setprecision(2);

charge = 7.00;

cout << "You owe \$" << charge << " dollars.
" << endl;
}
else if(total_minutes > 30.00 && total_minutes <=1440.0)
{
cout << fixed << showpoint << setprecision(2);

charge = 7.00 + (((total_minutes) - 30) * 1.50);

cout << "You owe \$" << charge << " dollars.
" << endl;
}

}
}

// end of S if

//----------------------------------------------------

system("pause");
return 0;
}

**** I want to know how to write and input a time such that in the output:
6:31 - 4:43 = 1 hour and 48 minutes instead of 2 hours and -12 minutes.

Also how would you write the time in a 12 Hour standard time of am/pm compared to 24 Hour military time?

--------
Hello Peter.
I see you were quick to read my answer. Actually, there is a problem with the code which I found by adding more test cases. The minuteDiff function represents the start time and end times in fractional hours, so the the difference in time could have fractional hours. For example, if the difference in time was 20 minutes, this would be represented as 0.33333333... hours. When multiplied by 60, to get minutes, this would be represented as 19.999999 minutes. When the time is returned as an integer, it is returned as 19 minutes. It is truncated, not rounded. This is the danger when using floating point math. If I had made the code more complicated, and handled the hours and minutes separately, this problem would not have occurred. However, there is a fix.
Instead of returning like this: return (int)(timeDiff * 60);
Do this: return (int)(timeDiff * 60 + 0.5);
That will aromatically do the correct rounding.

Best regards
Zlatko

---------------------------------------

Hello Peter.

To do your time calculation, you have to think of the different cases and decide what they mean. For example, what does it mean if the start time is less than the end time. Say the start time is 10:00 and the end time is 11:00. That is a simple case, and the time difference is simply the end time minus the start time.

What if the start time is 11:00 and the end time is 1:00. Here the start time is greater than the end time. The logical conclusion is that we passed the rollover time of the clock. For a 12 hour clock, the time difference would be 1 hour to get from 11 to 12 plus 1 hour to get from 12 to 1.

The other case is when start time is equal to the end time. Is that:
a) a trip of 0 minutes, or
b) on a 12 hour clock, a trip if 12 hours, and on a military clock a trip if 24 hours ?
I would assume the answer is (b).

These are the types of things you should be thinking of when faced with a new problem to solve.

The next thing is to define a function to do your calculation. By defining a function, you will have a reusable piece of code which will not clutter your main. You know you are taking in hours and minutes for start and end times. I'll tell you now that if you want to handle both military time and civilian time, you need a flag to signify the choice. Also, after thinking about the problem a bit, you might realize that expressing the result as a difference in minutes will be quite useful because it is easy to convert minutes into hours and minutes. The hours is minutesDiff / 60, and minutes is minuteDiff % 60.

int minuteDiff(int hourStart, int minuteStart, int hourEnd, int minuteEnd, bool military);

It calculates the difference in minutes between a start time and an end time using military or civilian calculations.

Now, before you rush into your coding, write some self checking tests. What would you expect from a call like this:
minuteDiff(10, 00, 10, 01, false) ?
You would expect a result of 1 minute.
minuteDiff(10, 00, 10, 00, false) ?
Well, according to our rules above, this is a 12 hour trip, so you'd expect a result of 12*60 minutes.

You can use the assert macro to check your expectations. Here is my test function of the minuteDiff function.

#include <assert.h>
void minuteDiff_test(void)
{
// Test civilian time
assert(minuteDiff(10, 00, 10, 01, false) == 1);
assert(minuteDiff(10, 15, 11, 30, false) == 45+30);

assert(minuteDiff(10, 00, 10, 00, false) == 12*60);
assert(minuteDiff(10, 01, 10, 00, false) == 12*60-1);
assert(minuteDiff(10, 00, 1, 30, false) == 120+60+30);

// Test military time
assert(minuteDiff(10, 00, 10, 01, true) == 1);
assert(minuteDiff(10, 15, 11, 30, true) == 45+30);

assert(minuteDiff(10, 00, 10, 00, true) == 24*60);
assert(minuteDiff(10, 01, 10, 00, true) == 24*60-1);
assert(minuteDiff(10, 00, 1, 30, true) == 14*60+60+30);
}

Try putting in a case with an incorrect expected result to see how the assert behaves when it is false. For example, try:
assert(minuteDiff(10, 01, 10, 00, true) == -999);
If you do that, you will see how it looks when the minuteDiff function does not return the expected result.

Writing your tests first gives your mind time to subconsciously think about the problem and its different cases.

Finally, I'll give you the code for the minuteDiff. The code becomes quite simple if you allow yourself to convert the hours and minutes into fractional hours. Here is the code. Try reading through it, and if you have questions about it, let me know.

Best regards
Zlatko

int minuteDiff(int hourStart, int minuteStart, int hourEnd, int minuteEnd, bool military)
{
double timeStart = hourStart + minuteStart / 60.0;
double timeEnd = hourEnd + minuteEnd / 60.0;
double timeDiff = 0;

if (timeStart < timeEnd)
{
timeDiff = timeEnd - timeStart;
}
else
{
int rollover;
if (military) rollover = 24;
else rollover = 12;
timeDiff = rollover - timeStart + timeEnd;
}
return (int)(timeDiff * 60);
}

---------- FOLLOW-UP ----------

QUESTION: I use Dev C++ and the assert(minuteDiff) is not working.

Make sure to have
#include <assert.h>
at the top of your program.

You might be interested in the test case I used to find the rounding problem.
I added this code to the minuteDiff_test function

for(int minS = 0; minS < 60; ++minS)
{
for(int minE = 0; minE < 60; ++minE)
{
assert(minuteDiff(10, minS, 11, minE, false) == 60-minS+minE);
}
}

It has two nested loops to generate all combinations of start and end minutes so all fractions of hours are tested. Creating good test code can be as challenging as writing the original program.

C++

Volunteer

#### Zlatko

##### Expertise

No longer taking questions.

##### Experience

No longer taking questions.

Education/Credentials
No longer taking questions.