C++/C++ Time-in and Time-out problem
Expert: Joseph Moore - 10/6/2009
QuestionQUESTION: Good day Sir.
I want to make a simple Daily Time Record system. I need to know how to input the TIME-IN and TIME-OUT in this format, HH:MM and then get the total hours worked. Can you give me an example of this? Thank you very much for reading my letter. Best regards.
ANSWER: Hi, Josef.
The code below is one way to do this. I don't know that it's the best way, but it is one way to do it and it is easy to implement. It makes some assumptions and doesn't do a lot of error checking, but it works for simple input data. In cases where the second time is less than the first time, it'll give weird results, I'm sure. For a real time clock system, you would want a full time stamp with full date so that you can determine a true amount of time worked. I've commented the relevant sections of code. If you have any questions about this code, feel free to ask.
#include <iostream>
using namespace std;
bool parseTime(char* _timeStr, int& _hour, int& _min)
{
// Make sure a pointer was passed in
if (NULL == _timeStr)
return false;
// Hours starts at the string passed in, minutes we figure out in a second
char* hourStr = _timeStr;
char* minStr = NULL;
// Loop through the string looking for the : character
char* curChar = _timeStr;
while (*curChar)
{
if (':' == *curChar)
{
// Found our minutes string. NULL terminate the hour string and set the minute string.
*curChar = '\0';
minStr = curChar + 1;
break;
}
++curChar;
}
// If no minute string was found, error
if (NULL == minStr)
return false;
// Convert the strings to integers and store them
_hour = atoi(hourStr);
_min = atoi(minStr);
// Restore the : character (could also use the "curChar" variable for this, but this way is more fun)
*(minStr - 1) = ':';
// Test for invalid values
if (_hour < 0 || _hour > 23)
return false;
if (_min < 0 || _min > 59)
return false;
// Theoretical success!
return true;
}
void main()
{
char time1[80];
char time2[80];
cin >> time1;
cin >> time2;
int hour1, min1;
int hour2, min2;
if (!parseTime(time1, hour1, min1))
{
cout << "Error parsing time 1: " << time1 << ". Invalid time format.\n";
exit(-1);
}
if (!parseTime(time2, hour2, min2))
{
cout << "Error parsing time 2: " << time2 << ". Invalid time format.\n";
exit(-1);
}
// Hours worked and minutes worked
int hoursWorked = hour2 - hour1;
int minsWorked = min2 - min1;
// It is possible that a full hour was not worked, meaning the minutes would be negative.
if (minsWorked < 0)
{
// If that is the case, deduct one hour and add 60 minutes. Since minutes is negative, this
// yields the actual minutes worked (IE, -4 becomes 56).
--hoursWorked;
minsWorked += 60;
}
cout << "Time worked: " << hoursWorked << " hours, " << minsWorked << " minutes.\n";
}
---------- FOLLOW-UP ----------
QUESTION: Good day sir, here I am again. Just a follow up question sir. When I entered 08:00 for time-in and 17:01 for time-out, while replacing the last line of code with this one, cout<<hoursWorked<<":"<<minsWorked<<endl; it shows an output like this one; 9:1. How could I make this output like this, 09:01 instead of 9:1? I changed all int to float and the precision to 2 floating point but it still 9:1. Another thing is that, if I time-in on or before 08:00 and time-out on or after 17:00, it will still output an 8 hrs.
I hope you still answer my questions sir. God bless you.
Sincerely,
Josef Alarka
AnswerHi, Josef.
To format the numbers, you'll want to use printf:
printf("Time worked -- %02d:%02d", hoursWorked, minsWorked);
The 02 before each d in the printf specify that it needs to be accurate to 2 digits and it will fill out 0's in the empty spots.
Also, I'm not entirely sure what you're asking with your last part. Do you want it to limit to 8 hours and not display any hours over 8? If that's the case, just add a couple of if blocks to the code after you calculate hoursWorked and minsWorked.
Check first to see if hoursWorked is > 8, and limit it to 8 if it is greater. Then, check if minsWorked is >= 8, and if it is, set minsWorked to 0.
Ok, hopefully that clears it all up. If you have any further questions, don't hesitate to ask.