I'm looking for a way to print out milliseconds in this format using C++:
cout << hours << " Hours : " << minutes << " Minutes : " << seconds << " Seconds : " << milliseconds << " Milliseconds" << endl;
I know there are a ton of duplicate questions about this. But none of them really handle how to get the remainder in milliseconds. There are a few that do this using Java, but I want a solution in C++.
Edit:
I wanted to clarify the question. I'm looking to take a time value that I get for the time it takes a program to run and print out that time in a legible format for the user. Getting the standard hr:min:sec was straight forward. But including any remaining milliseconds was tripping me up.
std::string format_duration( std::chrono::milliseconds ms ) {
using namespace std::chrono;
auto secs = duration_cast<seconds>(ms);
ms -= duration_cast<milliseconds>(secs);
auto mins = duration_cast<minutes>(secs);
secs -= duration_cast<seconds>(mins);
auto hour = duration_cast<hours>(mins);
mins -= duration_cast<minutes>(hour);
std::stringstream ss;
ss << hour.count() << " Hours : " << mins.count() << " Minutes : " << secs.count() << " Seconds : " << ms.count() << " Milliseconds";
return ss.str();
}
live example.
Extending this to days/years/etc should be easy (there isn't a predefined std::chrono duration type for days/years/etc prior to c++20 however).
But I can do better.
template<class Duration>
struct split_duration {
Duration d;
std::chrono::milliseconds leftover;
split_duration( std::chrono::milliseconds ms ):
d( std::chrono::duration_cast<Duration>(ms) ),
leftover( ms - std::chrono::duration_cast<std::chrono::milliseconds>(d) )
{}
};
template<class...Durations>
std::tuple<Durations...> durations( std::chrono::milliseconds ms ) {
std::tuple<std::optional<split_duration<Durations>>...> tmp;
( (void)(
(void)std::get<std::optional<split_duration<Durations>>>(tmp).emplace( ms ),
ms = std::get<std::optional<split_duration<Durations>>>(tmp)->leftover
), ...
);
return std::make_tuple( std::get<std::optional<split_duration<Durations>>>( tmp )->d... );
}
template<class T>
struct tag_t {};
template<class T>
constexpr tag_t<T> tag = {};
inline std::string duration_name( tag_t<std::chrono::milliseconds> ) { return "ms"; }
inline std::string duration_name( tag_t<std::chrono::seconds> ) { return "Seconds"; }
inline std::string duration_name( tag_t<std::chrono::minutes> ) { return "Minutes"; }
inline std::string duration_name( tag_t<std::chrono::hours> ) { return "Hours"; }
// inline std::string duration_name( tag_t<std::chrono::days> ) { return "Days"; }
// inline std::string duration_name( tag_t<std::chrono::years> ) { return "Years"; }
template<class...Durations>
std::string format_duration( std::chrono::milliseconds ms ) {
auto split = durations<Durations...>(ms);
std::stringstream ss;
(
(void)( ss << duration_name(tag<Durations>) << ": " << std::get<Durations>(split).count() << " " ), ...
);
return ss.str();
}
Days/Years requires c++20, everything else is c++17.
You just call format_durations<Durations...>( some_ms ) and out comes a formatted string based off the Durations.... You do have to do it from most-to-least significant.
durations<Durations...> gives you a tuple breakdown of the time that has to be most-to-least; you could then reorder that before formatting if you chose.
Duplicate duration types leads to compile time errors, as std::get dies a horrible ambiguous death.
Live example.
Maybe you're looking for something like this:
#include <iostream>
using namespace std;
int main() {
//Value chosen to be 1 hour, 1 minute, 1 second, and 1 millisecond
long milli = 3661001;
//3600000 milliseconds in an hour
long hr = milli / 3600000;
milli = milli - 3600000 * hr;
//60000 milliseconds in a minute
long min = milli / 60000;
milli = milli - 60000 * min;
//1000 milliseconds in a second
long sec = milli / 1000;
milli = milli - 1000 * sec;
cout << hr << " hours and " << min << " minutes and " << sec << " seconds and " << milli << " milliseconds." << endl;
}
int milliseconds = ...;
int seconds = milliseconds / 1000;
milliseconds %= 1000;
int minutes = seconds / 60;
seconds %= 60;
int hours = minutes / 60;
minutes %= 60;
cout << hours << " Hours : " << minutes << " Minutes : " << seconds << " Seconds : " << milliseconds << " Milliseconds" << endl;
Not exactly what you're looking for, but if you're only accessing the current time, this will work:
#include <chrono>
auto ms = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::high_resolution_clock::now().time_since_epoch());
const auto seconds = std::chrono::duration_cast<std::chrono::seconds>(ms);
ms -= seconds;
You can then add ms.count() to your cout, even if it isn't the actual remainder of the time you originally look at.
Edit: This method should be faster than using a modulus.
// Online IDE - Code Editor, Compiler, Interpreter
#include <stdio.h>
#include <stdint.h>
uint32_t DAYS_IN_MILLISECONDS = 86400000;
uint32_t HOURS_IN_MILLISECONDS = 3600000;
uint16_t MINUTES_IN_MILLISECONDS = 60000;
uint16_t SECONDS_IN_MILLISECONDS = 1000;
int main()
{
uint32_t total_milliseconds = 23*60*60000 + 100 + 1000;
uint8_t days = total_milliseconds / DAYS_IN_MILLISECONDS;
uint8_t hours = (total_milliseconds - days*DAYS_IN_MILLISECONDS) / HOURS_IN_MILLISECONDS;
uint8_t minutes = (total_milliseconds - days*DAYS_IN_MILLISECONDS - hours*HOURS_IN_MILLISECONDS) / MINUTES_IN_MILLISECONDS;
uint8_t seconds = (total_milliseconds - days*DAYS_IN_MILLISECONDS - hours*HOURS_IN_MILLISECONDS - minutes*MINUTES_IN_MILLISECONDS) / SECONDS_IN_MILLISECONDS;
uint8_t milliseconds = total_milliseconds - days*DAYS_IN_MILLISECONDS - hours*HOURS_IN_MILLISECONDS - minutes*MINUTES_IN_MILLISECONDS - seconds*SECONDS_IN_MILLISECONDS;
printf("%i:days %i:hours %i:minutes %i:seconds %i:milliseconds", days, hours, minutes, seconds, milliseconds);
return 0;
}
#ifndef DATETIME_H_
#define DATETIME_H_
/* Useful Constants */
#define SECS_PER_MIN (60UL)
#define SECS_PER_HOUR (3600UL)
#define SECS_PER_DAY (SECS_PER_HOUR * 24L)
#define DAYS_PER_WEEK (7L)
#define SECS_PER_WEEK (SECS_PER_DAY * DAYS_PER_WEEK)
#define SECS_PER_YEAR (SECS_PER_WEEK * 52L)
#define SECS_YR_2000 (946681200UL)
/* Useful Macros for getting elapsed time */
/** Get just seconds part of given Unix time */
#define numberOfSeconds(_time_) (_time_ % SECS_PER_MIN)
/** Get just minutes part of given Unix time */
#define numberOfMinutes(_time_) ((_time_ / SECS_PER_MIN) % SECS_PER_MIN)
/** Get just hours part of given Unix time */
#define numberOfHours(_time_) (( _time_% SECS_PER_DAY) / SECS_PER_HOUR)
/** Get day of week from given Unix time */
#define dayOfWeek(_time_) (( _time_ / SECS_PER_DAY + 4) % DAYS_PER_WEEK) // 0 = Sunday
/** Get elapsed days since 1970-01-01 from given Unix time */
#define elapsedDays(_time_) ( _time_ / SECS_PER_DAY) // this is number of days since Jan 1 1970
/** Get quantity of seconds since midnight from given Unix time */
#define elapsedSecsToday(_time_) (_time_ % SECS_PER_DAY) // the number of seconds since last midnight
/** Get Unix time of midnight at start of day from given Unix time */
#define previousMidnight(_time_) (( _time_ / SECS_PER_DAY) * SECS_PER_DAY) // time at the start of the given day
/** Get Unix time of midnight at end of day from given just Unix time */
#define nextMidnight(_time_) ( previousMidnight(_time_) + SECS_PER_DAY ) // time at the end of the given day
/** Get quantity of seconds since midnight at start of previous Sunday from given Unix time */
#define elapsedSecsThisWeek(_time_) (elapsedSecsToday(_time_) + (dayOfWeek(_time_) * SECS_PER_DAY) )
#endif /* DATETIME_H_ */
Sample Code :
unsigned long long s = 1 * 10 ;
unsigned long long m = 1 * 60 * 20;
unsigned long long h = 1 * 60 * 60 * 3;
unsigned long long d = 1 * 60 * 60 * 24 * 60;
unsigned long long M = 1 * 60 * 60 * 24 * 30 * 5;
unsigned long long y = 1 * 60 * 60 * 24 * 30 * 12 * 6;
//unsigned long long timeInSec = s + m + h + d + M + y;
unsigned long long timeInSec = s + m + h + d;
long long seconds = numberOfSeconds(timeInSec);
long long minutes = numberOfMinutes(timeInSec);
long long hours = numberOfHours(timeInSec);
long long day = dayOfWeek(timeInSec);
long long _elapsedDays = elapsedDays(timeInSec);
long long _elapsedSecsToday = elapsedSecsToday(timeInSec);
Not that I do not find interesting the other solutions, and it is my humble monkey way of working... always very near of the assembly code ... in the previous solutions, there is way too many variables created to achieve the goal.. in my exemple, only 2 variables are created, a string: result, an int8_t: n, plus a parameter in the function declaration, so the milliseconds are passed to the function using a INT: value
#include <string>
using namespace std;
// milliseconds to DDD HH:MM:SS.mmm , days are displayed if > 0
string ToDDHHMMSSmmm(int value)
{
string result=""; uint8_t n=value/86400000;
if (n>0) {result=to_string(n)+' ';}
value-=86400000*n; n=value/3600000; if(n<10) result+='0';
result+=to_string(n); value-=3600000*n;
n=value/60000; result+=':'; if(n<10) result+='0';
result+=to_string(n); value-=60000*n;
n=value/1000; result+=':'; if(n<10) result+='0';
result+=to_string(n); value-=1000*n;
result+='.'; if(value<100) result+='0';
if(value<10) result+='0';
result+=to_string(value);
return result;
}
1- a string result is created empty
2- a byte (8 bit int) is created(n) as the milliseconds passed to the
int parameter named value is divided by 86400000 (representing
the quantity of millisec per day)
3- if n is greater than 0, the numbers of days(max 255 days !) is added
to the string result.
4- using the same variables, n(the previously calculated days) will be
multiplied by the same number, and the result is subtracted from the
variable value. now n is set to the value divided by 3600000.
5- if n<10, we have only one digit for the hours, so add a char '0' to
the string result.
6- and convert + add to the string the value of n.
7- same principle for the minutes, the seconds, and the last part
the 3 digit milliseconds.
8- the string is built as the calculation are done, and the return
string is always in the perfect format (DDD) HH:MM:SS.mmm
The bytes used are as follow int32 for the value 4
int8 for the work 1
String 13 to 16 max (if days > 0)
...for a total of 21 Bytes, the large numbers are never stored in variables, they remain in the code and are calculated in the register of the cpu or mcu only. To be even nearer of ASSEMBLY, I should not used std::string and std::to_string, instead, pointers and using 0x20 for spaces, 0x3a for semi colons, and adding 0x30 to any digit values to create the ASCII directly in memory.
Two types of output
#include <iostream>
using namespace std;
int main() {
//Value chosen to be 1 hour, 1 minute, 1 second, and 1 millisecond
long milli = 3661001;
// hours
int hr = (milli / (1000 * 60 * 60)) % 24;
// minutes
int min = (milli / (1000 * 60)) % 60;
// seconds
int sec = (milli / 1000) % 60;
// milliseconds
int mill = milli % 1000;
char msg[10];
sprintf(
msg,
"%02d hours and %02d minutes and %02d seconds and %02d milliseconds.\n",
hr,
min,
sec,
mill
);
printf(msg);
cout << hr << " hours and " << min << " minutes and " << sec << " seconds and " << mill << " milliseconds." << endl;
}
Related
I'm trying to make a program to convert military time to standard time, am just having a problem outputting two zeroes for times such as 1300/1:00pm, it outputs as 1:0pm
int mtime, mins, hrs;
cout<<"Military to Standard Time"<<endl<<"Enter time: ";
cin>>mtime;
if (mtime >= 0 && mtime <= 2400)
{
if (mtime >= 1200)
{
mtime = mtime - 1200;
hrs = mtime / 100;
mins = mtime % 100;
cout<<hrs<<":"<<mins<<" P.M.";
}
else
hrs = mtime / 100;
mins = mtime % 100;
cout<<hrs<<":"<<mins<<" A.M.";
}
else
cout<<"Error, Please Enter Military Time 0000-2400"<<endl;
First, the data is wrong.
Second, if you want to cout 03 rather than 3, you can use
/*
*setw(2):The out put data with is 2 position
*setfill('0'):If the data is not enough 2 position, such 3 is only 1 position,
* so will fill the output data by zero
*/
cout<<setfill('0')<<setw(2)<<mins;
One solution is to conditionally print a 0 if the minutes is less than 10:
#include <iostream>
int main()
{
int hrs = 1;
int mins = 3;
std::cout << hrs << ":" << (mins<10?"0":"") << mins << " A.M.\n";
mins = 15;
std::cout << hrs << ":" << (mins<10?"0":"") << mins << " A.M.\n";
}
Output:
1:03 A.M.
1:15 A.M.
Add curly braces to both the else blocks. Kindly avoid such basic Syntax errors.
else {
hrs = mtime / 100;
mins = mtime % 100;
cout<<hrs<<":"<<mins<<" A.M.";
}
else {
cout<<"Error, Please Enter Military Time 0000-2400<<endl;"
}
im tasked with taking a users inputted start and stop times, and compute and display the difference. We need a header file MyTime that contains the structure with hours, minutes, and seconds. My main function prompts the user to input the time and it goes directly into the MyTime Structure. Then, DetermineElapsedTime function is called and passed two pointers to the two structures containing the user entered times, Then store the pointer it returns in a type "Pointer to MyTime" Variable. That is where im having the trouble. A hint is given as well for this: "Declare a static MyTime structure in DetermineElapsedTime, store the elapsed time in it, then return its address. Returning a pointer or reference to an automatic object is always wrong".
Any Help is greatly appreciated; what i have so far is below. Right now my TimeDiff variable that calls the DetermineElapsedTime function is returning garbage. And im not sure if i set up the structures properly. I am new to C++ so any guidance is deeply appreciated. Thanks.
MAIN FUNCTION:
#include <iostream>
#include "C1A7E1_MyTime.h"
using namespace std;
MyTime* DetermineElapsedTime(const MyTime* StartTime, const MyTime* StopTime);
int main()
{
MyTime StartTime, StopTime;
MyTime *TimeDiff;
for (int i = 1; i <= 3; i++);
{
cout << "Please enter a Start and Stop Time that is space seperated on "
"the same line in the following colon-delimited format "
"(HH:MM:SS): ";
// Declare Colon delimiters
char Colon1, Colon2, Colon3, Colon4;
// Get users input
cin >> StartTime.hours >> Colon1 >> StartTime.minutes >> Colon2
>> StartTime.seconds >> StopTime.hours >> Colon3
>> StopTime.minutes >> Colon4 >> StopTime.seconds;
TimeDiff = DetermineElapsedTime(&StartTime, &StopTime);
cout << "\nThe time elapsed from " << StartTime.hours << Colon1
<< StartTime.minutes << Colon2 << StartTime.seconds << " to "
<< StopTime.hours << Colon3 << StopTime.minutes
<< Colon4 << StopTime.seconds << " is " << TimeDiff;
}
return 0;
}
DetermineElapsedTime Function:
#include "C1A7E1_MyTime.h"
#define HR_SECONDS 3600;
#define MIN_SECONDS 60;
using namespace std;
MyTime *DetermineElapsedTime(const MyTime *StartTime, const MyTime *StopTime)
{
// Declare static MyTime structure to store elapsed time in
MyTime static ElapsedTime;
// Pull out Start Time in seconds
long int Start_Hr = StartTime->hours * HR_SECONDS;
int Start_Min = StartTime->minutes * MIN_SECONDS;
int Start_Sec = StartTime->seconds;
// Total the number of seconds in start time
int TotalStart = Start_Hr + Start_Min + Start_Sec;
// Pull out Stop Time in seconds
long int Stop_Hr = StopTime->hours * HR_SECONDS;
int Stop_Min = StopTime->minutes * MIN_SECONDS;
int Stop_Sec = StopTime->seconds;
// Total the number of seconds in stop time
int TotalStop = Stop_Hr + Stop_Min + Stop_Sec;
// Find the difference in start/stop time
long int TimeDiff = (TotalStop - TotalStart);
// If stop time is less than start time (new day) then make it positive
if (TimeDiff <= 0)
{
TimeDiff = -TimeDiff;
}
// Find time difference in hours
int ElapsedHr = TimeDiff / HR_SECONDS;
ElapsedTime.hours = ElapsedHr;
// Find time difference in minutes
int FirstSub = ElapsedHr * HR_SECONDS;
int remainingSeconds = (TimeDiff) - FirstSub;
int ElapsedMin = remainingSeconds / MIN_SECONDS;
ElapsedTime.minutes = ElapsedMin;
// Find time difference in seconds
int SecondSub = ElapsedMin * MIN_SECONDS;
remainingSeconds = remainingSeconds - SecondSub;
int ElapsedSec = remainingSeconds;
ElapsedTime.seconds = ElapsedSec;
//Return address of elapsed time
return(&ElapsedTime);
}
MyTime Structure / Header File
#ifndef C1A7E1_MYTIME_H // Header Guard
#define C1A7E1_MYTIME_H
//Structure Definition and declaration of structur variables
struct MyTime
{
int hours, minutes, seconds;
};
#endif
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
So we are supposed to convert 453456 seconds into years, days, hours, minutes, and seconds.
However, I cannot seem to get past years.
Here is what I have so far:
#include<iostream>
using namespace std;
int main (){
int secDis;
int years;
const int yearsSec = 31536000;
int days;
cout << "Please give me the time of travel in seconds.";
cin >> secDis;
years = secDis/yearsSec;
days = (yearsSec%secDis) / 1440; /*idk if I am on the right track*/
cout << "You have been traveling for: "
<< years << days;
If it is 453456 seconds it should be 0 years 5 days 5 hours 57 minutes and 36 secs.
//I hate my math skills.
You have the order of secDis and yearsSec reversed in the line to compute the number of days.
Also, the number of seconds in a day are: 24 x 60 x 60, which is 86400. You are off by an order of 60.
The number of seconds left after the number of years is (secDis % yearsSec).
Hence, you need to use:
days = (secDis % yearsSec ) / 86400;
#HowardHinnant has provided a Swiss-army-knife date library for such questions, see this Q&A, after which using
std::cout << human_readable_difference(second_point{453456s},
second_point{0s});}
will indeed print:
0 years 0 months 5 days 5 hours 57 minutes 36 seconds
I really like TemplateRex's answer! (upvoted it).
But here's a way to solve this problem with just the <chrono> library, assuming your definition that a year is 365 days (a pretty coarse assumption):
#include <chrono>
#include <iostream>
int
main()
{
using namespace std;
using namespace std::chrono;
using days = duration<int, ratio_multiply<ratio<24>, hours::period>>;
using years = duration<int, ratio_multiply<ratio<365>, days::period>>;
auto s = 453456s;
auto y = duration_cast<years>(s);
s -= y;
auto d = duration_cast<days>(s);
s -= d;
auto h = duration_cast<hours>(s);
s -= h;
auto m = duration_cast<minutes>(s);
s -= m;
std::cout << y.count() << " years "
<< d.count() << " days "
<< h.count() << " hours "
<< m.count() << " minutes "
<< s.count() << " seconds\n";
}
<chrono> already has units hours, minutes and seconds. Just add two more units for days and years, and now you can just use duration_cast to successively truncate the seconds into coarser units, and then subtract that truncation out from the seconds (a modulo operation). Just continue with finer and finer units until you are down to your finest unit (seconds in this example). The above program outputs:
0 years 5 days 5 hours 57 minutes 36 seconds
This lets <chrono> do all the conversions for you, reducing the chance of errors.
You want the remainder from the division secDis / yearsSec, which is secDis % yearsSec – not yearsSec % secDis.
(That is, to get the remainder, replace /with %.)
I believe it gets easier if you define the number of seconds in each unit of time explicitly:
// Let the computer do the computing.
const int perMinute = 60;
const int perHour = 60 * perMinute;
const int perDay = 24 * perHour;
const int perYear = 365 * perDay;
and spell out every step of the computations:
int years = totalSeconds / perYear;
int daySeconds = totalSeconds % perYear;
int days = daySeconds / perDay;
int hourSeconds = daySeconds % perDay;
int hours = hourSeconds / perHour;
// ...
i'm seriously new to this QT stuff. this may be a silly question but i couldn't find any answer for that. I have gone through qt documentation and searched internet to find answer to this question.
my question is that suppose there is an "integer variable" which has a duration value in seconds. I need that one to convert into QTime object to return as a QTime. How can I do this in Qt creator??..
int seekTime;
int seconds = QTime().secsTo(duration);
seekTime = seconds * bytePos/totalSize;
return seekTime;
i need to return this seekTime variable as a QTime object how can I do this?
thanx in advance..!
This should work.
QTime t = QTime().addSecs(duration);
Here's a small program I tried:
#include <iostream>
#include <QTime>
int main()
{
int durationInSeconds = 40;
QTime t = QTime().addSecs(durationInSeconds);
std::cout << "h: " << t.hour() << ", m: " << t.minute() << " s: " << t.second() << ", ms: " << t.msec() << std::endl;
return 0;
}
This is the output I got:
h: 0, m: 0 s: 40, ms: 0
Update
A QTime can also be constructed to represent the seconds as:
int durationInSeconds = 40;
QTime t(0, 0, durationInSeconds);
Update 2
The function secsTo can be used to compute the difference in seconds between two instances of QTime. Here's the documentation:
int QTime::secsTo ( const QTime & t ) const
Returns the number of seconds from this time to t. If t is earlier than this time, the number of seconds returned is negative.
Because QTime measures time within a day and there are 86400 seconds in a day, the result is always between -86400 and 86400.
secsTo() does not take into account any milliseconds.
Say you have:
QTime t1(0, 1, 0:
QTime t2(0, 0, 45);
int secs = t2.secsTo(t1); // secs should be equal to 15.
secs = t1.secsTo(t2); // secs should be equal to -15.
Hope that clarifies the intended behaviour of QTime::secsTo a little bit.