Finding the difference between two times of day - c++

Input prompt asks for a starting time, and then a duration time where it returns two times: one time where they are added, and one where they are subtracted. I've gotten the basics of them, but when I try and do it for certain times (ex: 1:18 and 10:39) I get a negative error:
X Input of 1:18 10:39 : expected [11:57, 2:39] but found [11:57, -9:-21]
Here's the code that does the calculations:
int timeHours, timeMinutes, durHours, durMinutes;
cout << " Time: ";
cin >> timeHours;
cin.get();
cin >> timeMinutes;
cout << " Duration: ";
cin >> durHours;
cin.get();
cin >> durMinutes;
int time, duration, after, before, afterHours, afterMinutes, beforeHours, beforeMinutes;
const int MINUTES_IN_DAY = 60 * 24;
time = (timeHours * 60) + timeMinutes;
duration = (durHours * 60) + durMinutes;
after = time + duration;
before = time - duration;
afterHours = after / 60 % 12;
afterMinutes = after % 60;
beforeHours = before / 60;
beforeMinutes = before % 60;
cout << endl;
cout << durHours << ":" << setfill('0') << setw(2) << durMinutes << " hours after, and before, "
<< timeHours << ":" << timeMinutes << " is [" << afterHours << ":" << setw(2) << afterMinutes << ", "
<< beforeHours << ":" << setw(2) << beforeMinutes << "]" << endl;
The failed test above shows that the sum (1:18 + 10:39) works but the difference (1:18 - 10:39) does not work. It gives me "-9:-21" which should be able to be fixed by adding 24 hours, which is even what my assignment suggests: "This is easily done by adding a day (or two or three) to before when calculating the difference" but when I add 1440 (60 * 24) to the "before" initialization:
before = (time - duration) + MINUTES_IN_DAY;
and convert back from minutes to normal time I get 14:39, which is 2:39, but in 24 hour form, not 12 (incidentally it also makes all the other tests which were passing now failing). I think there's some hint when it says "by adding a day (or two or three) since obviously 1440 is different from 1440*2 or *3, but I'm not seeing it and I have to be missing something obvious. I know I'll have to fix it for midnight as well but I'll change that later. If anyone knows what I'm trying to explain, I'd really appreciate it

Usually, when working with times/dates it's easier to make yourself a function to convert a human-readable date to milliseconds or seconds (and vice versa) and build up from that base. In your case, you'll just add/subtract the two time-marks in seconds for example:
long long time = toSec(timeHours, timeMinutes, timeSeconds);
long long duration = toSec(durHours, durMinutes, durSeconds);
string after = toDate(time + duration);//somethig like 12:34:00 (hh:mm:ss)
string before = toDate(time - duration);
however, putting effort in making such conversion functions would be an overcomplication if all you use them for is a one-time calculation.

( like you suggested to add MINUTES_IN_DAY) to solve the negative values problem you can use the %MINUTES_IN_DAY to avoid the overflow caused by adding MINUTES_IN_DAY to a positive value
before = ((time - duration)+MINUTES_IN_DAY)%MINUTES_IN_DAY;

Related

How to make a variable input be any number I put in (C++)

I'm new to coding and am having trouble with one of my first projects.
So I have to basically type a number and then have that number spit out some answers involving things like addition and multiplication. (ex. if I put in 5, one of the answers is to simply multiply that 5 by 30. Or another adds it).
The issue is that the only way I can get that number to be different and give the corresponding answers is if I go into the code and change the integer assigned to the variable, which is pretty counterintuitive.
I've tried deleting the variable, setting = 0, moving it around; nothing is working.
stocks = 0;
investment = stocks * 30;
charges = investment * .015;
total = charges + investment;
cout << "Cindy, how much are you investing?";
cin >> stocks;
cout << endl;
some of the code there. Line in question is the "stocks = 0;" one. After that, it's the other variables that would be output with their associated variables. Any help would be appreciated, I hope this makes sense for what I'm asking! Thanks in advance
You will have to cin the number.
#include <iostream>
int main() {
int stocks;
std::cout << "Cindy, how much are you investing?";
std::cin >> stocks;
investment = stocks * 30;
charges = investment * .015;
total = charges + investment;
std::cout << "The total charges would be " << total << "." << std::endl;
}

C++ program if statements in function not executing. Seems Logically errored

I am making a program in C++, that takes the user entered time in U.S. standard time and converts it to military time. The body of the main code is executing fine, but the problem comes in the body of my function beginning with the if statements. I am wondering why this is occurring; am fairly new with c++. Here's my code if you have question feel free to ask or need explanation of what the program is supposed to be doing.
#include <iostream>
#include <string>
using namespace std;
void militaryConversion(string am_pmPart_st, string firstPartofTime, string secondPartofTime){
// Converts they obtained strings, but first we must concatenate the two parts into one string
string concatenatedTime;
int militaryTime;
cout << "test1" << endl;
concatenatedTime = firstPartofTime + secondPartofTime;
if(firstPartofTime == "12")
{
cout << "Corresponding military time is: " << concatenatedTime << " hours" << endl;
}
else if(am_pmPart_st == " am")
{
if (concatenatedTime.length() < 4){
cout << "Corresponding military time is: " << concatenatedTime << " hours"<< endl;
}
}
else if(am_pmPart_st == " pm")
{
int castedTime;
castedTime = stoi(concatenatedTime); //This is where we convert the string to int because its the only place it matters
militaryTime = castedTime + 1200;
cout << "Corresponding military time is: " << militaryTime << " hours" << endl;
}
}
int main()
{
char DELEMETER = ':';
char DELEMETER_sp = ' ';
string time, firstPartofTime, secondPartofTime, am_pmPart_st, loweredAM_PM;
cout << "Enter the time in the format of: HH:MM AM/PM ";
getline(cin, time);
firstPartofTime = time.substr(0, time.find(DELEMETER));
cout << "The first digits of time " << firstPartofTime << endl;
secondPartofTime = time.substr(time.find(DELEMETER) + 1, time.find(DELEMETER_sp)-1);
cout << "The second set of digits " << secondPartofTime << endl;
am_pmPart_st = time.substr(time.find(DELEMETER_sp), time.size());
cout << "The am/pm part is:" << am_pmPart_st << endl;
for(int i=0; am_pmPart_st[i]; i++) am_pmPart_st[i] = tolower(am_pmPart_st[i]); //Converts am/pm to lowercase
cout << am_pmPart_st << endl;
militaryConversion(am_pmPart_st, firstPartofTime, secondPartofTime);
}
First, your question is vague because it does say what is happening that should not be happening. However, I think I can see what is happening. When you check for the hour part of the time in the first condition, you check for "12" first. However, you never correct for am or pm within that 12. My recommendation would be to check for 12 inside the am (12 am == 0000 hours) and pm (12 pm == 1200 hours). In am you will need to check for 12 and subtract 1200 from the time, in pm you will need to check for 12 and not add 1200 to the time.
substr takes two parameters. The first is the start position and the second is the length. When you call secondPartofTime = time.substr(time.find(DELEMETER) + 1, time.find(DELEMETER_sp)-1); you are mistakenly passing the second parameter as the end position, not the length.
Instead, you can do:
int startPos = time.find(DELEMETER) + 1;
int endPos = time.find(DELEMETER_sp) - 1;
secondPartofTime = time.substr(startPos, endPos - startPos + 1);
Ideally, you should check the return values of find and handle the case when npos is returned so you don't crash on invalid user input.
Input which doesn't follow the HH:MM AM/PM form is creating a problem. (Exactly 5 characters for HH:MM (including colon))
You have an if-else based decision tree, where one if is not accompanied by an else. The lack of else is why your program is not giving any output
string.substr() has some issues as explained by MFisherKDX

How can you switch a float to a time format?

Hello I am a begineer so please be nice :)..
In C++, if I have a float like 12.5 or 13.25, how can I convert this to show as 12:30 and 13:15?
Thank you so much.
float time = ...;
Simly casting the float to an int will chop off the fractional part, leaving you with the hours.
int hour = static_cast<int>(time);
If you subtract the hours, then all that's left is the minutes as fractions of an hour. If you multiply this by 60, you get the remainder in minutes. Again, cast to an int to chop off the seconds, leaving only minutes.
int minute = static_cast<int>((time-hour)*60);
Then display the hours, and a colon. To display the minutes properly, tell it to always use a width of 2 characters, and fill in the blanks with a '0'. This makes it say 02 instead of just 2.
std::cout << hour << ':' << std::setw(2) << std::fill('0') << minute;
As with any problem, you need to break it down into its component parts and attack each one separately.
What you have:
A floating-point number of hours.
What you need:
To print the integer number of hours.
To print a ":"
To print the fractional number of hours as a proportion of 60 minutes.
So, now, we can address each part of the problem.
Let's say the input is:
const float time = 13.25;
The first part is quite easy — truncating a floating-point variable can be done using the mathematical floor function, but all you really need to do is cast to int to get the same effect:
std::cout << (unsigned int)time;
The second part is also really easy:
std::cout << ':';
The third part takes a little more work. We need to discard everything but the fractional part. We can do that by subtracting the integer part:
time - (unsigned int)time
Then we must transform the value so that instead of being a proportion of the range [0.00,1.00), it's a proportion of the range [0,60), simply by multiplying by 60:
60 * (time - (unsigned int)time)
We're left with:
const float time = 13.25;
std::cout << (unsigned int)time;
std::cout << ':';
std::cout << 60 * (time - (unsigned int)time);
// result: 13:15
(live demo)
For a general solution, we also want to show a leading zero if there's only one digit:
const float time = 12.10;
std::cout << (unsigned int)time;
std::cout << ':';
std::cout << std::setw(2) << std::setfill('0');
std::cout << 60 * ((time - (unsigned int)time) / 100);
// result: 12:06
In reality, to avoid rounding errors and possible overflows, you'd drop the float altogether and simply store integer minutes:
const unsigned int time_mins = (12*60) + 6;
std::cout << (time_mins / 60);
std::cout << ':';
std::cout << std::setw(2) << std::setfill('0');
std::cout << (time_mins % 60);
// result: 12:06
(live demo)
Or, y'know, use an actual time/date type.

lvalue required as left operand of assignment error via if statement

I've looked at similar questions, but being a total newbie at this, they haven't helped much, when I try to run my final if statement I run into this error, how can I make my cout statement clearer? Its intended purpose is to output how many bags of garbage it can accept, how many the user is trying to give it, and how many bags will be left over if it cannot take them all.
while(( reg < 50) && (met< 20) && (glass < 20))
{
reg=reg+reg; met=met+met; glass=glass+glass;
cout<< " I have enough "<< endl;
if(reg+=reg > 50){
cout<< "I can only accept " << 50 - (reg+=reg) << "of your " << (reg+=reg)<<" regular bags of garbage, I'll leave the other " << 50 - (reg+= reg)<< " I'll leave the other " << reg- (50 - reg+=reg)<< endl;
}
50 - reg += reg;
operator+= has lower precedence than operator-. The above statement is interpreted as:
(50 - reg) += reg;
which won't work. You probably wanted:
50 - (reg += reg);

Converting ascii substr to int

first year college having problem converting ascii into int.
The problem is this piece of code
unsigned short iminutes = ((minutes[3]-48)*10) + (minutes[4]-48);
When I run this on codeblocks at home it returns an incorrect value, when I run it again I get a different incorrect value.
When I run it at on Borlands at college, the screen just ups and disappears before I can read it, so I can't use the system clock here either.
It's Easter hols now so even though I'm at college, I can't annoy my tutors because they're not.
#include <iostream.h>
#include <conio.h>
#include <string>
//#include <time.h>
//#include <ctype.h>
using namespace std;
int main() {
bool q = false;
do {
// convert hours to minutes ... then total all the minutes
// multiply total minutes by $25.00/hr
// format (hh:mm:ss)
string theTime;
cout << "\t\tPlease enter time " << endl;
cout <<"\t\t";
cin >> theTime;
cout << "\t\t"<< theTime << "\n\n";
string hours = theTime.substr (0, 2);
cout <<"\t\t"<< hours << endl;
unsigned short ihours = (((hours[0]-48)*10 + (hours[1] -48))*60);
cout << "\t\t"<< ihours << endl;
string minutes = theTime.substr (3, 2);
cout <<"\t\t"<< minutes << endl;
unsigned short iminutes = ((minutes[3]-48)*10) + (minutes[4]-48);
cout << "\t\t" << iminutes << endl;
cout << "\n\n\t\tTotal Minutes " <<(ihours + iminutes);
cout << "\n\n\t\tTotal Value " <<(ihours + iminutes)*(25.00/60) << "\n\n";
}
while (!q);
cout << "\t\tPress any key to continue ...";
getch();
return 0;
}
You set minutes to be a substring of theTime. So minutes has 2 characters. The first one starting at position 0 within minutes.
So this
unsigned short iminutes = ((minutes[3]-48)*10) + (minutes[4]-48);
is wrong as it accesses characters 3 and 4 in minutes which don't exist, because minutes is only two characters long. It only has characters as positions 0 and 1.
should be this
unsigned short iminutes = ((minutes[0]-48)*10) + (minutes[1]-48);
or you could use this:
unsigned short iminutes = ((theTime[3]-48)*10) + (theTime[4]-48);
The problem is that even though you get the characters at position 3 and 4 from the original string, the new string is just two characters (i.e. only have index 0 and 1).
istringstream iss(theTime.substr(0, 2));
iss >> ihour;