Convert milliseconds since midnight into a time object - c++

I have an incoming data feed that gives me an int with the number of milliseconds since midnight.
I'd like to convert it into some sort of time object so I can display the time.
For example, 1000 = 00:00:01
Is there a simple way to do this? Do I need a time struct?
Thank you!

x = ms / 1000
seconds = x % 60
x /= 60
minutes = x % 60
x /= 60
hours = x % 24
Then you can cout the time that has been parsed for you. This is only for duration since midnight. It won't show you the date.

You could use a little helper struct for this, but this could be a little bit to much for your simple request:
#include <iostream>
#include <iomanip>
struct MidnightTime{
MidnightTime(unsigned int miliseconds) :
seconds((miliseconds/1000) % 60),
minutes((miliseconds/60000) % 60),
hours((miliseconds/3600000) % 24){}
unsigned int seconds, minutes, hours;
};
std::ostream& operator<<(std::ostream& out, const MidnightTime& t){
out << std::setfill('0') << std::setw(2) << t.hours << ":" <<
std::setfill('0') << std::setw(2) << t.minutes << ":" <<
std::setfill('0') << std::setw(2) << t.seconds;
return out;
}
int main(){
std::cout << MidnightTime(1000) << std::endl; // will result in 00:00:01
return 0;
}

Related

How to measure execution time of a function?

I've searched SO and found relevant questions answered but I'm confused about the three different clock definitions. Considering I compile with Mingw on Windows;
I wonder whether the code below is OK or not? (I do not really need nanoseconds or microseconds precision; just testing...)
Which one should I use?
std::chrono::high_resolution_clock
std::chrono::system_clock
std::chrono::steady_clock
#include <iostream>
#include <chrono>
...
...
...
void printTimeElapsed(
std::chrono::high_resolution_clock::time_point t0,
std::chrono::high_resolution_clock::time_point t1)
{
int64_t hh; // hour
int64_t mm; // min
int64_t ss; // sec
int64_t ml; // millisec
int64_t mc; // microsec
int64_t ns; // nanosec
ns = std::chrono::duration_cast<std::chrono::nanoseconds>(t1 - t0).count();
std::cout << ns << std::endl;
mc = ns / 1000;
ns %= 1000;
ml = mc / 1000;
mc %= 1000;
ss = ml / 1000;
ml %= 1000;
mm = ss / 60;
ss %= 60;
hh = mm / 60;
mm %= 60;
std::cout
<< std::setfill('0') << std::setw(3) << hh << ":"
<< std::setfill('0') << std::setw(2) << mm << ":"
<< std::setfill('0') << std::setw(2) << ss << "."
<< std::setfill('0') << std::setw(3) << ml << "."
<< std::setfill('0') << std::setw(3) << mc << "."
<< std::setfill('0') << std::setw(3) << ns << std::endl;
return;
}
...
...
...
int main(
int argc,
char *argv[])
{
std::chrono::high_resolution_clock::time_point t0;
std::chrono::high_resolution_clock::time_point t1;
...
...
t0 = std::chrono::high_resolution_clock::now();
/* call the function to be measured */
t1 = std::chrono::high_resolution_clock::now();
printTimeElapsed(t0, t1);
...
...
return (0);
}
system_clock is not steady: is subject to time adjustments.
high_resolution_clock is not guaranteed to be steady.
It means for users to use steady_clock for measurement, and because of this, implementers need to make the steady_clock of a high resolution.
Windows implementation of steady_clock should be based on QueryPerformanceCounter / QueryPerformanceFrequency, which is highest resolution of available API. This is true for MSVC, need to check for MinGW.

How to convert seconds to hh:mm:ss.millisecond format c++?

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.
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";
}
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}));
}
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;
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";
}

How do I convert from seconds to minutes using this library?

I have a program that uses this popular library, however I am struggling to use it to convert from seconds to minutes
The following code...
#include <iostream>
#include "units.h"
int main(int argc, const char * argv[])
{
{
long double one = 1.0;
units::time::second_t seconds;
units::time::minute_t minutes(one);
seconds = minutes;
std::cout << "1 minute is " << seconds << std::endl;
}
{
long double one = 1.0;
units::time::second_t seconds(one);
units::time::minute_t minutes;
minutes = seconds;
std::cout << "1 second is " << minutes << std::endl;
}
return 0;
}
produces...
1 minute is 60 s
1 second is 1 s
however, I would have expected it to produce...
1 minute is 60 s
1 second is .016666667 m
The library offers a units::convert method, check the doc here.
Here's a working snippet:
long double one = 1.0;
units::time::second_t seconds(one);
units::time::minute_t minutes;
minutes = seconds;
std::cout << "1 second is " << minutes << std::endl;
std::cout << "1 second is "
<< units::convert<units::time::seconds, units::time::minutes>(seconds)
<< std::endl;
For more, I suggest searching in the doc.
I don't know the library you are using, but C++11 added the std::chrono::duration class that seems to be able to do what you want:
#include <chrono>
#include <iostream>
int main()
{
{
std::chrono::minutes minutes(1);
std::chrono::seconds seconds;
seconds = minutes;
std::cout << "1 minute is " << seconds.count() << std::endl;
}
{
std::chrono::seconds seconds(1);
using fMinutes = std::chrono::duration<float, std::chrono::minutes::period>;
fMinutes minutes = seconds;
std::cout << "1 second is " << minutes.count() << std::endl;
}
return 0;
}
Note that the default std::chrono::minutes uses an integer counter, and thus reports that 1 second is 0 minutes. That is why I define my own float-minutes.
In any case, the above program produces the following output:
1 minute is 60
1 second is 0.0166667

Problems with Add method in TimeUnit class

#include <iostream>
#include <string>
#include <sstream>
using namespace std;
class TimeUnit
{
public:
TimeUnit(int m, int s)
{
this -> minutes = m;
this -> seconds = s;
}
string ToString()
{
ostringstream o;
o << minutes << " minutes and " << seconds << " seconds." << endl;
return o.str();
}
void Simplify()
{
if (seconds >= 60)
{
minutes += seconds / 60;
seconds %= 60;
}
}
TimeUnit Add(TimeUnit t2)
{
TimeUnit t3;
t3.seconds = seconds + t2.seconds;
if(t3.seconds >= 60)
{
t2.minutes += 1;
t3.seconds -= 60;
}
t3.minutes = minutes + t2.minutes;
return t3;
}
private:
int minutes;
int seconds;
};
int main(){
cout << "Hello World!" << endl;
TimeUnit t1(2,30);
cout << "Time1:" << t1.ToString() << endl;
TimeUnit t2(3,119);
cout << "Time2:" << t2.ToString();
t2.Simplify();
cout << " simplified: " << t2.ToString() << endl;
cout << "Added: " << t1.Add(t2).ToString() << endl;
//cout << " t1 + t2: " << (t1 + t2).ToString() << endl;
/*cout << "Postfix increment: " << (t2++).ToString() << endl;
cout << "After Postfix increment: " << t2.ToString() << endl;
++t2;
cout << "Prefix increment: " << t2.ToString() << endl;*/
}
I'm having problems with my Add method. Xcode is giving me this error: "No matching constructor for initialization of TimeUnit"
Could someone please tell me what I am doing wrong? I've literally tried everything that I know how to do, but I can't even get it to compile with this method.
Here are the instructions from my professor:
The TimeUnit class should be able to hold a time consisting of Minutes
and Seconds. It should have the following methods:
A constructor that takes a Minute and Second as parameters ToString()
- Should return the string equivilant of the time. "M minutes S seconds." Test1 Simplify() - This method should take the time and
simplify it. If the seconds is 60 seconds or over, it should reduce
the seconds down to below 60 and increase the minutes. For example, 2
Min 121 seconds should become 4 minutes 1 second. Test2 Add(t2) -
Should return a new time that is the simplified addition of the two
times Test3 operator + should do the same thing as Add Test4 pre and
postfix ++: should increase the time by 1 second and simplify Test5
In your TimeUnit::Add function, you tried to initialize t3 with default constructor. However, your TimeUnit doesn't have one:
TimeUnit Add(TimeUnit t2)
{
TimeUnit t3; ///<<<---- here
///.....
}
Try update TimeUnit::Add to this way:
TimeUnit Add(const TimeUnit& t2)
{
return TimeUnit(this->minutes+t2.minutes, this->seconds+t2.seconds);
}
The specific problem is because there is no TimeUnit::TimeUnit() defined, only TimeUnit(const int &m, const int &s).

get future time value

#include <time.h>
#include <iostream>
using namespace std;
int main()
{
time_t current = time(0);
cout << ctime(&current) << endl;
return 0;
}
How can I get the future time, say 1 hour later, from the current time?
time(2) returns the number of seconds since 1970-01-01 00:00:00 +0000 (UTC). One hour later would be current + 3600.
time_t current = time(0);
time_t inOneHour = current + (60*60); // 60 minutes of 60 sec.
cout << "Now: " << ctime(&current) << "\n"
<< "In 1 hour: " << ctime(&inOneHour)
<< "\n";