This question already has answers here:
Converting seconds to hours and minutes and seconds
(11 answers)
Closed 9 months ago.
I am trying to solve a problem where I have a total seconds variable, from which I am trying to determine the hours, minutes and seconds.
I do not want to use any external libraries for this task.
What I have noticed is that my seconds variable seems to result in 1 less than the actual value when it is in int form,
but when it is in double form the answer is correct. Why is this?
I would welcome a different approach, perhaps using the remainder operator.
// Example program
#include <iostream>
#include <string>
int main()
{
int total_seconds;
total_seconds = 3870;
int hours, minutes, seconds;
double total_h, total_m, total_s;
int total_hours_int, total_minutes_int;
total_h = (double)total_seconds / 3600;
total_hours_int = total_seconds / 3600;
hours = total_hours_int;
total_m = (total_h - total_hours_int) * 60;
total_minutes_int = (total_h - total_hours_int) * 60;
minutes = total_minutes_int;
total_s = ((double)total_m - total_minutes_int) * 60;
seconds = ((double)total_m - total_minutes_int) * 60;
//seconds = (double)total_s;
std:: cout << hours;
std:: cout << minutes;
std:: cout << total_s;
std:: cout << seconds;
}
Output : 143029
Update:
The answer below was given before the C++98 tag was added to the question.
The chono library is available since C++11, so you can use it only from that version onwards.
You haven't given any context for this task.
My asnwer below assumes you need to solve the problem in any valid C++ manner (i.e. that it is not mandatory the caculate the numbers "by hand").
If this is the case, you can use the C++ chrono library for that, as shown below. This solution is shorter and less error-prone, and avoids the type issues you had altogether.
The main class I used is std::chrono::duration and it's helper types (as you can see in the link), as well as std::chrono::duration_cast.
#include <iostream>
#include <chrono>
int main()
{
int total_seconds = 3870;
std::chrono::seconds total_secs(total_seconds);
auto hours = std::chrono::duration_cast<std::chrono::hours>(total_secs);
auto mins = std::chrono::duration_cast<std::chrono::minutes>(total_secs - hours);
auto secs = std::chrono::duration_cast<std::chrono::seconds>(total_secs - hours - mins);
std::cout << "totals seconds: " << total_secs.count() << std::endl;
std::cout << " hours: " << hours.count() << std::endl;
std::cout << " minutes: " << mins.count() << std::endl;
std::cout << " seconds: " << secs.count() << std::endl;
}
Output:
totals seconds: 3870
hours: 1
minutes: 4
seconds: 30
I've reopened answear since it was updated to C++98.
Before C++11 it can be done nicely using standard library:
#include <iostream>
#include <string>
#include <ctime>
int main()
{
int seconds;
while (std::cin >> seconds) {
std::tm t = {};
t.tm_sec = seconds;
t.tm_mday = 1;
mktime(&t);
t.tm_hour += t.tm_yday * 24;
char buf[32];
strftime(buf, sizeof(buf), "%H:%M:%S", &t);
std::cout << t.tm_yday << ' ' << seconds << " = " << buf << '\n';
}
return 0;
}
https://godbolt.org/z/ceWWfoP6P
one of the problems I'm working on requires an input of two time values (being in hours, minutes and seconds)in a 24h00 format. I have already declared my variables, input and output statements with regards to my main program. I'm just having trouble with my void statement CalcDiff to calculate the difference of the two time inputs. All values have been declared of type int. Should inputs(eg. sec and sec2) be compared first to see which is greater before calculating the difference? I'm assuming the order of variables would be important too(calculating the difference of the hours before the minutes, before the seconds)? I'm new to C++ so my apologies if I'm missing anything obvious.
// Computes time difference of two time periods in 24h00 format
// Time periods are input
#include <iostream>
using namespace std;
int seconds,seconds2, minutes, minutes2, hours, hours2;
void CalcDiff(int seconds, int seconds2 int minutes, int minutes2, int
hours, int hours2);
int main()
{
int sec, sec2, min, min2, hr, hr2, diff;
cout << "Enter the first time." << endl;
cout << "Enter hours, minutes and seconds: ";
cin >> hr >> min >> sec;
cout << "Enter the second time." << endl;
cout << "Enter hours, minutes and seconds: ";
cin >> hr2 >> min2 >> sec2;
CalcDiff(int sec, int sec2, int min, int min2, int hr, int hr2,
diff);
cout << endl << "Difference in times: " << hr << ":" << min << ":"
<< sec;
cout << " - " << hr2 << ":" << min2 << ":" << sec2;
return 0;
}
void CalcDiff(int seconds, int seconds2, int minutes, int minutes2, int
hour, int hour2, diff)
Use <chrono> plus an existing library.
#include "date.h"
#include <iostream>
int
main()
{
std::chrono::seconds t1, t2;
std::cout << "Enter the first time [h]h:mm:ss: ";
std::cin >> date::parse("%T", t1);
if (std::cin.fail())
return 1;
std::cout << "Enter the second time [h]h:mm:ss: ";
std::cin >> date::parse(" %T", t2);
if (std::cin.fail())
return 1;
std::cout << date::format("Difference in times: %T\n", t1 - t2);
}
The above library is free, open-source, and being proposed for standardization.
I had the same problem and my solution was this code, my perspective is to get both times in seconds and then subtract them to know the difference. time calculations are made inside the IF statement. the rest of the code is to print the results, I added many variables to try to make it more explicit and understandable.
#include <iostream>
using namespace std;
int main()
{
int h1,h2,m1,m2,s1,s2;
long TotalSeconds = 0;
cout << "Enter the first time." << endl;
cout << "Enter hours, minutes and seconds: ";
cin >> h1 >> m1 >> s1;
cout << "Enter the second time." << endl;
cout << "Enter hours, minutes and seconds: ";
cin >> h2 >> m2 >> s2;
// Difference Between Times IN Seconds
// this code must be in your function
if( h1 > h2 ){
TotalSeconds += 86400 - ((h1*3600)+(m1*60)+(s1));
TotalSeconds += ((h2*3600)+(m2*60)+(s2));
}else{
// Time 2 - Time 1
TotalSeconds = ((h2*3600)+(m2*60)+(s2)) - ((h1*3600)+(m1*60)+(s1));
}
cout << "Total Seconds: " << TotalSeconds << endl;
cout << "Time Difference :\t";
long hours, minutes, seconds;
hours = TotalSeconds / 3600;
cout << hours << ":";
TotalSeconds -= hours*3600;
minutes = TotalSeconds / 60;
cout << minutes << ":";
TotalSeconds -= minutes*60;
seconds = TotalSeconds;
cout << seconds << endl;
return 0;
}
Another Example using C' Style, in this example you must input time string like this 01:23:11
#include <stdio.h>
#include <stdlib.h>
int main()
{
int h1,h2,m1,m2,s1,s2;
long segundos = 0;
// Hora Inicial
scanf("%i : %i : %i",&h1,&m1,&s1);
// Hora Final
scanf("%i : %i : %i",&h2,&m2,&s2);
// HORAS
if( h1 > h2 ){
segundos += 86400 - ((h1*3600)+(m1*60)+(s1));
segundos += ((h2*3600)+(m2*60)+(s2));
}else{
// Tiempo 2 - Tiempo 1
segundos = ((h2*3600)+(m2*60)+(s2)) - ((h1*3600)+(m1*60)+(s1));
}
printf("%ld",segundos);
return 0;
}
Aside from there already existing classes to handle this, here is a solution idea with explanation.
First of all, sec, sec2, min, min2... this is a list of different variables. If you have such a long list, this is a sign that something is amiss. This is C++, so use OOP. That is, use classes.
One header for such a class could be
class Time {
private:
unsigned char seconds;
unsigned char minutes;
unsigned char hours;
public:
Time(const unsigned char _seconds, const unsigned char _minutes,
const unsigned char __hours);
Time(const unsigned int _seconds);
Time difference(const Time& other) const;
unsigned int to_total_seconds() const;
}
This is a far cleaner approach - you don't need all the code right where you use it. Implementations:
Time Time::difference(const Time& other) const {
int difference_seconds = (int) this.to_total_seconds() - (int) other.to_total_seconds();
return Time((unsigned int) std::abs(difference_seconds));
}
unsigned int Time::to_total_seconds() const{
return seconds + 60.*minutes + 60*60*hours;
}
Time::Time(const unsigned int _seconds){
seconds = _seconds % (60*60);
minutes = (_seconds / 60) % 60;
hours = _seconds / (60*60);
}
Time::Time(const unsigned char _seconds, const unsigned char _minutes,
const unsigned char __hours) :
seconds(_seconds), minutes(_minutes), hours(_hours) {
assert(seconds < 60);
assert(minutes < 60);
}
Another approach would be to directly store the total seconds.
I mean, you could do things like doing actual subtractions, like doing difference 6:12 to 4:50 by subtracting 50 from 12 in minutes, resulting in 38 with a remainder, then 6 minus (4 + remainder) = 1 -> 1:38 difference. But why do that when you can simply subtract the seconds and take their absolute value?
But more importantly, keep your main clean. Large procedural code is a clear sign that a class is missing.
(Of course you'll have to add something to the code that gets the values out, preferably a printer. Since there are possibilities for inconsistence, public members are not recommended here.)
Try using std::chrono
void calcDiff(int h1, int m1, int s1, int h2, int m2, int s2){
std::chrono::seconds d = std::chrono::hours(h2-h1)
+ std::chrono::minutes(m2-m1)
+ std::chrono::seconds(s2-s1);
std::cout << std::chrono::duration_cast<std::chrono::hours>(d).count() << "h" <<
std::chrono::duration_cast<std::chrono::minutes>(d % std::chrono::hours(1)).count() << "m" <<
std::chrono::duration_cast<std::chrono::seconds>(d % std::chrono::minutes(1)).count() << "s" << std::endl;
}
int main(){
calcDiff(13, 30, 45, 18, 40, 20); // 5h9m35s
calcDiff(20, 30, 45, 18, 40, 20); // -1h-50m-25s
return 0;
}
The negative result might be a little wierd, but i am sure you can make it work whatever way you want.
I decided to go with converting the minutes and hours to seconds and work the difference for the time periods through a void function I called CalcDiff. I used three referenced variables, FinSec, FinMin and FinHr to store the differences after converting the new DiffSec to the new values.
My program for the void statement is:
void CalcDiff(int seconds, int seconds2, int minutes, int minutes2, int
hour, int hour2, int& FinSec, int& FinMin, int& FinHr)
{
int TotalSec1, TotalSec2, DiffSec, tempMin;
TotalSec1= (hour*3600)+(minutes*60)+seconds;
TotalSec2= (hour2*3600)+(minutes2*60)+seconds2;
if(TotalSec1>TotalSec2)
DiffSec = TotalSec1 - TotalSec2;
else
DiffSec = TotalSec2 - TotalSec1;
FinSec = DiffSec%60;
tempMin = DiffSec/60;
FinMin = tempMin%60;
FinHr = FinMin/60;
}
first of all the syntax of function call should be
CalcDiff( sec, sec2, min, min2, hr, hr2);
instead of
CalcDiff(int sec, int sec2, int min, int min2, int hr, int hr2,
diff);
in the main section
function definition the code should be
void CalcDiff(int seconds, int seconds2, int minutes, int minutes2, int
hour, int hour2, diff)
{
\\ write the code for subtraction here
}
My function turns seconds to minutes. The problem is, if I have a number where the remainder is less than 10, it will just give give me remainder without a 0 before the remainder.
For example,
368 seconds would just turn to 6:8
360 would turn to 6:0
361 to 6:1
I would like
368 seconds to turn to 6:08
360 to 6:00
361 to 6:01
void toMinutesAndSeconds(int inSeconds, int &outMinutes, int &outSeconds) {
outMinutes = inSeconds / 60;
outSeconds = inSeconds % 60;
}
I'm outputting to a text file.
That's a matter of how you output your values. That value itself doesn't have "leading zeros".
#include <iostream>
#include <iomanip>
void toMinutesAndSeconds(int inSeconds, int &outMinutes, int &outSeconds)
{
outMinutes = inSeconds / 60;
outSeconds = inSeconds % 60;
}
int main()
{
int minutes = 0;
int seconds = 0;
toMinutesAndSeconds(368, minutes, seconds);
std::cout << std::setfill('0') << std::setw(2) << minutes << ":"
<< std::setfill('0') << std::setw(2) << seconds;
return 0;
}
prints
06:08
Here's a bit of code from another question which adds 29.0 minutes to 60.0 seconds and displays the result in hours:
cout <<
static_cast<quantity<hour_base_unit::unit_type>>
(quantity<time>{29.0 * minute_base_unit::unit_type()} + 60.0 * seconds)
<< endl;
What's the recommended way to define minutes so that the above expression can be written as:
cout <<
static_cast<quantity<hour_base_unit::unit_type>>
(29.0 * minutes + 60.0 * seconds)
<< endl;
If you can, I would recommend using C++14's <chrono> facilities for this. They are very nice. (I know this is not technically an answer to his question, but it might save him a lot of work).
#include <iostream>
#include <chrono>
int main () {
using namespace std::chrono;
std::cout << duration_cast<hours>(29min + 60s).count() << std::endl;
}
I am attempting to handle the problem that I have not encountered before.
I tried this link, but it did no good to me.
Error in system header file /usr/include/i386_types.h
I have attempted to look for possible soultions from similar problems, but it did not help me solve my own problem.
I reordered and did semi colon, but I still get the annoying error
Dealing with the in file included error:
g++ -Wall -Wextra -c clock.cpp clock_main.cpp In file included from /usr/include/machine/_types.h:34,
from /usr/include/sys/_types.h:33,
from /usr/include/_types.h:27,
from /usr/include/unistd.h:71,
from /usr/include/c++/4.2.1/i686-apple-darwin10/x86_64/bits/os_defines.h:61,
from /usr/include/c++/4.2.1/i686-apple-darwin10/x86_64/bits/c++config.h:41,
from /usr/include/c++/4.2.1/iostream:44,
from clock.cpp:2:
/usr/include/i386/_types.h:37: error: two or more data types in declaration of â__int8_tâ
In file included from /usr/include/machine/_types.h:34,
from /usr/include/sys/_types.h:33,
from /usr/include/_types.h:27,
from /usr/include/unistd.h:71,
from /usr/include/c++/4.2.1/i686-apple-darwin10/x86_64/bits/os_defines.h:61,
from /usr/include/c++/4.2.1/i686-apple-darwin10/x86_64/bits/c++config.h:41,
from /usr/include/c++/4.2.1/iostream:44,
from clock_main.cpp:2:
/usr/include/i386/_types.h:37: error: two or more data types in declaration of â__int8_tâ
and some files that contribute to the errors
clock_main.cpp
#include "clock.h"
#include <iostream> // line 2 cause of error by compiler
using namespace std;
int main(){
Clock clk_0 (86399); // 1 day - 1 sec
cout << "initial time" << endl;
clk_0.print_time();
++clk_0;
cout << "adding one second" << endl;
clk_0.print_time();
--clk_0;
cout << "subtracting one second" << endl;
clk_0.print_time();
return 0;
}
clock.h
#ifndef CLOCK_H
#define CLOCK_H
/*
We make a simple clock class
and we use the power of overloading operators
*/
class Clock{
public:
Clock (unsigned int i); // construct and conversion
void print_time() const; //formatted printout
void tick(); // add one second
void tock(); // subtract one second
Clock operator++() {tick(); return *this;}
Clock operator--() {tock(); return *this;}
~Clock() {};
private:
unsigned long tot_secs, secs, mins, hours, days;
}
#endif
clock.cpp
#include "clock.h"
#include <iostream> // the offending line
inline Clock::Clock(unsigned int i){
tot_secs = i;
secs = tot_secs % 60;
mins = (tot_secs / 60) % 60;
hours = (tot_secs / 3600) % 24;
days = tot_secs / 86400;
};
void Clock::tick(){
Clock temp = Clock (++tot_secs);
secs = temp.secs;
mins = temp.mins;
hours = temp.hours;
days = temp.days;
}
void Clock::tock(){
Clock temp = Clock (--tot_secs);
secs = temp.secs;
mins = temp.mins;
hours = temp.hours;
days = temp.days;
}
void Clock::print_time() const{
std::cout << days << " days: " << hours << " hours: " << mins <<
" minutes: " << secs << " seconds" << std::endl;
}
semicolon
class Clock{
public:
Clock (unsigned int i); // construct and conversion
void print_time() const; //formatted printout
void tick(); // add one second
void tock(); // subtract one second
Clock operator++() {tick(); return *this;}
Clock operator--() {tock(); return *this;}
~Clock() {};
private:
unsigned long tot_secs, secs, mins, hours, days;
} ;
// ^^