Reputation: 49
I need to convert seconds in to hh:mm:ss.milliseconds and I need that this format must be respected. I mean that hours, minutes and seconds must have 2 digits and milliseconds 3 digits. For example, if seconds = 3907.1 I would to obtain 01:05:07.100
#include <iostream>
#include <iomanip>
#include <fstream>
#include <string>
#include <stdio.h>
#include <sstream>
#include <math.h>
using namespace std;
int main()
{
double sec_tot = 3907.1;
double hour = sec_tot/3600; // seconds in hours
double hour_int;
double hour_fra = modf(hour, &hour_int );//split integer and decimal part of hours
double minutes = hour_fra*60; // dacimal hours in minutes
double minutes_int;
double minutes_fra = modf(minutes, &minutes_int); // split integer and decimal part of minutes
double seconds = minutes_fra*60; // decimal minutes in seconds
stringstream ss;
ss << ("%02lf", hour_int) << ":" << ("%02lf", minutes_int) << ":" << ("%02lf", seconds);
string time_obs_def = ss.str();
cout << time_obs_def << endl;
return 0;
}
but the output is 1:5:7.1 Thank you.
Upvotes: 2
Views: 13018
Reputation: 31
This will also add a leading zero to enforce hh:mm:ss format. If hh is 00, returns only mm:ss. ms are left out from this example, but easy to add.
#include <iostream>
std::string convertSecondsToHHMMSS (int value) {
std::string result;
// compute h, m, s
std::string h = std::to_string(value / 3600);
std::string m = std::to_string((value % 3600) / 60);
std::string s = std::to_string(value % 60);
// add leading zero if needed
std::string hh = std::string(2 - h.length(), '0') + h;
std::string mm = std::string(2 - m.length(), '0') + m;
std::string ss = std::string(2 - s.length(), '0') + s;
// return mm:ss if hh is 00
if (hh.compare("00") != 0) {
result = hh + ':' + mm + ":" + ss;
}
else {
result = mm + ":" + ss;
}
return result;
}
int main() {
std::cout << convertSecondsToHHMMSS(3601) << "\n";
std::cout << convertSecondsToHHMMSS(1111) << "\n";
std::cout << convertSecondsToHHMMSS(60) << "\n";
std::cout << convertSecondsToHHMMSS(12) << "\n";
std::cout << convertSecondsToHHMMSS(0) << "\n";
}
Upvotes: 1
Reputation: 218700
Coming in C++20:
#include <chrono>
#include <iostream>
using namespace std;
using namespace std::chrono;
int
main()
{
double sec_tot = 3907.1;
cout << format("{:%T}\n", round<milliseconds>(duration<double>{sec_tot}));
}
Upvotes: 3
Reputation: 117178
Nowadays you should probably use the chrono duration std::chrono::milliseconds for such a task, but if you'd like make our own type to support formatting, something like this should do it:
#include <iomanip> // std::setw & std::setfill
#include <iostream>
// your own type
struct seconds_t {
double value;
};
// ostream operator for your type:
std::ostream& operator<<(std::ostream& os, const seconds_t& v) {
// convert to milliseconds
int ms = static_cast<int>(v.value * 1000.);
int h = ms / (1000 * 60 * 60);
ms -= h * (1000 * 60 * 60);
int m = ms / (1000 * 60);
ms -= m * (1000 * 60);
int s = ms / 1000;
ms -= s * 1000;
return os << std::setfill('0') << std::setw(2) << h << ':' << std::setw(2) << m
<< ':' << std::setw(2) << s << '.' << std::setw(3) << ms;
}
int main() {
seconds_t m{3907.1};
std::cout << m << "\n";
}
Upvotes: 6
Reputation: 993
printf
style format specifiers do not work. You will need to use the stream manipulators to set the width and fill character.
ss << std:setw(2) << std::setfill('0') << hour_int;
Upvotes: 1