I have noticed strange behaviour when printing output to a stream. My code loops through a large dataset and, amongst other things, reads a timestamp from each item. The timestamp from the first item is stored so an elapsed time can be calculated.
CurTime = ev[i].MidasTimeStamp;
RunTimeElapsed = difftime(CurTime,StartTime);
cout << "StartTime: " << ctime(&StartTime) << "CurTime: " << ctime(&CurTime) << "Elapsed: " << RunTimeElapsed << " s" << endl;
The output printed to screen shows the same time printed twice e.g:
StartTime: Mon Sep 23 14:44:57 2013
CurTime: Mon Sep 23 14:44:57 2013
Elapsed: 360 s
But if split the print line into two:
cout << "StartTime: " << ctime(&StartTime);
cout << "CurTime: " << ctime(&CurTime) << "Elapsed: " << RunTimeElapsed << " s" << endl;
I get the expected output:
StartTime: Mon Sep 23 14:44:57 2013
CurTime: Mon Sep 23 14:50:57 2013
Elapsed: 360 s
The only change between the two outputs was to the cout line(s). This is easy enough to work around but I'd like to understand what's happening.
From the documentation on ctime:
The returned value points to an internal array whose validity or value
may be altered by any subsequent call to asctime or ctime.
The order of evaluation of subexpressions within the expression is unspecified. In particular, it is legal for the compiler to call ctime twice first, then call operator<< as necessary. This is what seems to happen in your case.
Related
I have a function which prints time_t values.
void Logger::describe()
{
cout << m_start_time << " " << m_end_time << "\n";
if (ctime(&m_start_time) == ctime(&m_end_time))
{
cout << "check1\n";
}
cout << m_vehicle->getPlate() << " " << ctime(&m_start_time) << " " << ctime(&m_end_time) << "\n";
}
// m_start_time and m_end_time are private variables of type time_t of the class Logger
For a sample output after waiting a couple of seconds I get
1634907786 1634907791
check1
bike1 Fri Oct 22 18:33:06 2021
Fri Oct 22 18:33:06 2021
As can be seen m_start_time and m_end_time are different but ctime returns the the same value. Can anyone help explain why ?
I'm using gcc 6.3.0 if it helps.
Read the information on the return value here: ctime
It is a pointer to a static string. You are not comparing the string content (see strcmp), only this pointer.
I am testing the time cost of opening a USB2Serial port n Centos 7.4. But I found it cost about 7ms for the first time. But it cost much more time in the next opening. If I increase the sleep time, run again, it costs more time except for the first open.
I am using usb2serial device from FTDI, the kernel driver is ftdi_sio.
Here is my code:
for (int i = 0; i < 10; i++)
{
steady_clock::time_point start = steady_clock::now();
int handle = open("/dev/ttyUSB0", O_RDWR| O_NONBLOCK | O_NDELAY);
steady_clock::time_point end = steady_clock::now();
std::cout << "Item " << i << ":" << " " << duration_cast<std::chrono::nanoseconds>(end-start).count()/1000000 << " ms" << endl;
usleep(10000); // us
close(handle);
}
The result is:
Item 0: 6 ms
Item 1: 76 ms
Item 2: 75 ms
Item 3: 75 ms
Item 4: 75 ms
Item 5: 76 ms
Item 6: 75 ms
Item 7: 75 ms
Item 8: 75 ms
Item 9: 74 ms
I just wonder why the open time becomes longer after the first time. Maybe need some other operation before close.
Anyone has met similar problem ? Or any comments? Thanks
std::chrono::duration_cast returns a std::chrono::duration object.
The printf function is an old C compatibility function, and as such knows nothing about C++ objects.
In short, what you're printing is not really the duration, instead you have undefined behavior! Considering you're on Ubuntu, then you're using either GCC or Clang, both compilers which should complain about that.
If you want to print the actual duration "count" then use the count member function, preferably together with std::cout to get type-safe conversions:
std::cout << "Item " << i << ": " << duration_cast<std::chrono::nanoseconds>(e1-s1).count() << " ns\n";
Or if your compiler can handle some of the changes in the upcoming C++20 standard (which defines an operator<< overload for durations):
std::cout << "Item " << i << ": " << duration_cast<std::chrono::nanoseconds>(e1-s1) << " ns\n";
The big lesson: Don't mix C++ and old C functions. They seldom mix very well.
You might also want to consider getting a few good books to help you learn C++ properly.
I was expecting the following code should print different time stamps t1 and t2, however the result shows t1 and t2 are the same. Where did I make the mistake?
#include<iostream>
#include<ctime>
using namespace std;
int main()
{
time_t t1 = time(NULL);
cout << "time now " << ctime(&t1) << endl;
time_t t2 = t1 + 10000.0;
cout << "time now " << ctime(&t1) << endl << " time later " << ctime(&t2) <<endl;
}
Result:
time now Thu Apr 28 20:37:03 2016
time now Thu Apr 28 20:37:03 2016
time later Thu Apr 28 20:37:03 2016
The answer to your question can be found in the manual page for the ctime() function:
The return value points to a statically allocated string which might
be overwritten by subsequent calls to any of the date and time
functions.
ctime() returns a pointer to an internal buffer it uses. Every time it's called, it returns a pointer to the same buffer:
cout << "time now " << ctime(&t1) << endl << " time later " << ctime(&t2) <<endl;
For this line of code, your compiler generated code that calls ctime() twice, then executes the << operator. But on the second call to ctime(), it overwrote the buffer with the second time, so when the << operator formats the output, because the result of the first call to ctime() is the same pointer, and the buffer that it points to has been overwritten by the second call to ctime(), you get the same time printed twice.
Thank you for posting a Minimal, Complete, and Verifiable example.
What is ctime actually returning? From cppreference:
Pointer to a static null-terminated character string holding the textual representation of date and time. The string may be shared between std::asctime and std::ctime, and may be overwritten on each invocation of any of those functions.
It likely works out that on your compiler, the later ctime() gets called first, then the newer ctime(), then both operator<<()s get evaluated - which emit the same char*. As a result of the unspecified order, your code has undefined behavior. On some compilers, it could work as you hoped it would! On yours, it happens not to.
If you separate out the two calls:
cout << "time now " << ctime(&t1) << endl;
cout << " time later " << ctime(&t2) <<endl;
you'd definitely and consistently see different values.
Quote from N1570 7.27.3 Time conversion functions:
Except for the strftime function, these functions each return a pointer to one of two
types of static objects: a broken-down time structure or an array of char. Execution of
any of the functions that return a pointer to one of these object types may overwrite the
information in any object of the same type pointed to by the value returned from any
previous call to any of them and the functions are not required to avoid data races with
each other.
This suggests that the contents pointed by what is returned from ctime() can be overwritten by another call of ctime(), so you will have to copy the result to use the result in one expression with no sequence point in that.
Try this:
#include<iostream>
#include<ctime>
#include<string>
using namespace std;
int main()
{
time_t t1 = time(NULL);
cout << "time now " << ctime(&t1) << endl;
time_t t2 = t1 + 10000.0;
string t1s = ctime(&t1);
string t2s = ctime(&t2);
cout << "time now " << t1s << endl << " time later " << t2s <<endl;
}
I'm trying to make a program wherein the user will input his/her birthday and the program will compute how many days, months, years, hours and minutes they've lived.
I've searched Google and I see there's a way to split the date into three to four parts.
I've copied this code and it seems to be working. It's just that I don't understand it. All the forums I've read don't help much either. Can anyone explain it to me?
time_t t = time(NULL);
tm* timePtr = localtime(&t);
cout << "seconds= " << timePtr->tm_sec << endl;
cout << "minutes = " << timePtr->tm_min << endl;
cout << "hours = " << timePtr->tm_hour << endl;
cout << "day of month = " << timePtr->tm_mday << endl;
cout << "month of year = " << timePtr->tm_mon << endl;
cout << "year = " << timePtr->tm_year + 1900 << endl;
cout << "weekday = " << timePtr->tm_wday << endl;
cout << "day of year = " << timePtr->tm_yday << endl;
cout << "daylight savings = " << timePtr->tm_isdst << endl;
In most computing environments, dates and times are a unified concept. The C runtime library (hence also C++) provides the type time_t which measures time (and dates) as the number of seconds since 1970-01-01T00:00:00 UTC.
The localtime() function takes a time_t and converts that into the calendar-like fields which humans are accustomed to, according to the local timezone (which is obtained from the computer—the timezone can also be specified specifically). There is another very similar call, gmtime() which does not consider the local timezone, but always uses the UTC timezone, formerly called GMT.
To do what you want, accept from the user their birth date, birth time, and timezone, and convert that into a time_t. Then subtract that from the current time() value. The difference is the number of seconds they have been alive. To be friendly, use gmtime() to convert that to years, months, days, hours, minutes, and seconds.
This is not standard C++ code. This is (also) POSIX code.
(The recent C++11 standard gives you <chrono> but few compilers implement it; on Linux you'll need GCC 4.6 or 4.7; there is also <ctime>)
See this answer to a question very related to yours.
As for time, gettimeofday, localtime, strftime they have well written reference documentation in the manual page. What don't you understand?
(follow the links I gave you and read the linked pages carefully).
Why RWTime is giving 1 hour more
#include <rw/rwtime.h>
#include <rw/rwdate.h>
#include <rw/rstream.h>
main(){
RWTime t; // Current time
RWTime d(RWTime::beginDST(1990, RWZone::local()));
cout << "Current time: " << RWDate(t) << " " << t <<
endl;
cout << "Start of DST, 1990: " << RWDate(d) << " " << d <<
endl;
}
Above program prints:
root#otp42mas:/home/nmsadm/sapna/cProgS# ./a.out
Current time: 10/27/10 10/27/10 17:08:06
Start of DST, 1990: 04/01/90 04/01/90 03:00:00
But date gives:
root#otp42mas:/home/nmsadm/sapna/cProgS# date
Wed Oct 27 16:08:10 IST 2010
My sixth sense is tingling, it tells me that the answer has something to do with the daylight savings time ... I'm not sure why, though ...
By default RWZone::local() will return an RWZone implementation based on North American DST transitions. RWZone::os() provides an RWZone implementation based DST transitions derived from the current system time zone. RWZone::local() can be updated to use RWZone::os() using:
RWZone::local(&RWZone::os());