C++ Equivalent for GetLocalTime in Linux (with milliseconds!) - c++

I have been searching for over an hour but I simply seem to not be able to find the solution!
I am looking for a function that gives me a similar struct as GetLocalTime on Windows does. The important thing for me is that this struct has hours, minutes, seconds and milliseconds.
localtime() does not include milliseconds and therefore I cannot use it!
I would apprechiate a solution that uses the standard library or another very small library since I am working on a Raspberry Pi and connot use large libraries like boost!

As it was mentioned above, there are not direct equivalent. If you can use C++ 11, <chrono> header allows to get the same result, but not in single call. You can use high_resolution_clock to get current Unix time in milliseconds, then you can get localtime C function to get time without milliseconds, and use current Unix time in milleseconds to find milliseconds count. It looks like you will have to write your own GetLocalTime implementation, but with C++ 11 it will not be complex.

GetLocalTime is not a usual Linux function.
Read time(7), you probably want clock_gettime(2), or (as commented by Joachim Pileborg), the older gettimeofday(2)
If you need some struct giving all of hours, minutes, seconds, milliseconds you have to code that yourself using localtime(3) and explicitly computing the millisecond part.
Something like the below code is printing the time with milliseconds
struct timespec ts = {0,0};
struct tm tm = {};
char timbuf[64];
if (clock_gettime(CLOCK_REALTIME, &ts))
{ perror("clock_gettime"), exit(EXIT_FAILURE);};
time_t tim = ts.tv_sec;
if (localtime(&tim, &tm))
{ perror("localtime"), exit(EXIT_FAILURE);};
if (strftime(timbuf, sizeof(timbuf), "%D %T", &tm))
{ perror("strftime"), exit(EXIT_FAILURE);};
printf("%s.%03d\n", timbuf, (int)(ts.tv_nsec/1000000));

You can use a combination of:
clock_gettime(CLOCK_REALTIME); returns local time, up to millisecond (of course constrained by the actual clock resolution); does not care of local timezone information, returns UTC time. Just use millisecond information (from tv_nsec field).
time(); returns local time, up to the second - no millisecond - also UTC time. time() results (a time_t) is easy to convert to the final format.
then convert time() result using localtime_r(); this sets up a structure very similar to Windows SYSTEMTIME; result is up to the second, and takes into account local timezone information.
finally set up the millisecond field using clock_gettime() results.
These routines are documented, not deprecated, portable.
You may need to call tzset() once (this sets the timezone information - a C global variable - from operating system environment - probably a heavy operation).

Related

Any difference between clock_gettime( CLOCK_REALTIME .... ) and time()?

A simple question: do time(...) and clock_gettime( CLOCK_REALTIME, ... ) produce the same time theoretically (in respect to seconds only)?
Here's what I mean:
time_t epoch;
time( &epoch );
and
struct timespec spec;
clock_gettime( CLOCK_REALTIME, &spec );
Are these two supposed to return exactly the same result (in respect to seconds)?
I "tested" this with changing time and time zones and epoch and spec.tv_sec always show the same result, but the documentation of CLOCK_REATIME confuses me a bit and I'm not sure, that they will always be the same.
Real world situation: I have a piece of code, which uses time. Now I want to have the time in milliseconds (which can be taken from spec.tv_nsec, multiplied by 1000000). So I think about removing time and using directly clock_gettime, but I'm not sure if this will remain the same in all situations.
The question is somehow related to Measure time in Linux - time vs clock vs getrusage vs clock_gettime vs gettimeofday vs timespec_get? but the information there was not enough for me.. I think.
[Note: I used the git master branch and v4.7 for the reference links below, x86 only, as I'm lazy.]
time() is in fact an alias for the equally named syscall, which calls get_seconds, happens at kernel/time/time.c. That syscall uses the get_seconds function to return the UNIX timestamp, which is read from the core timekeeping struct, more precisely from the "Current CLOCK_REALTIME time in seconds" field (xtime_sec).
clock_gettime() is a glibc function in sysdeps\unix\clock_gettime.c, which simply calls gettimeofday if the supplied clock ID is CLOCK_REALTIME, which is again backed by the equally named syscall (source is in the same time.c file, above). This one calls do_gettimeofday, which eventually ends up calling __getnstimeofday64, that queries... the very same xtime_sec field from the same struct as above.
Update:
As #MaximEgorushkin cleverly pointed out, a new vDSO mechanism hijacks (a good sign it is present, if your binary depends on linux-vdso.so.*) the clock_gettime call and redirects it to __vdso_clock_gettime. This one uses a new clock source management framework (gtod - Generic Time Of Day). A call to do_realtime, and it reads from a structure, struct vsyscall_gtod_data's wall_time_sec field. This structure is maintained by update_vsyscall, from the same timekeeper struct as the above.
tl;dr
The answer is: yes, they get the time from the same clock source.

How to get the local current time in seconds since epoch in C++ (MSVS)?

I need the local (with timezone offset) current time in seconds since epoch. The following code looks a bit clumzy because it creates an intermediate temporary structure tm which is superfluous. Why do I have to get time_t then convert it to tm in order to return to time_t? Is there a better way?
time_t ct = time(0);
tm lct = tm();
localtime_s(&lct, &ct);
ct = _mkgmtime(&lct);
If you want to get the local time (with time zone and DST applied) in portable C, then yes, it's generally a two-step procedure: starting with your time-since-the-epoch, first call localtime, then do something with the resulting broken-down struct tm. (Usually what I do next is call strftime.)
You can also call ctime to get a local time string directly.
The reason there are a lot of different function calls involved is that, unfortunately, there are several different time formats in use. (And the reason for that is that dates and times are complicated!) You can represent time as seconds-since-1970. You can represent it as a struct tm. You can represent it as a string (in one of several zillion formats). In Unix and Linux, you can represent it as a struct timeval or a struct timespec.
But one thing there isn't a straightforward or standard way to do, as you've discovered, is get local time as seconds-since-1970. But the reason for that is that it's not a very useful representation. In general, there are two things you might want to do with a date/time value: (1) perform computations on it or (2) display it to the user. If you want to display it to the user, you probably want to display it in local time, so there are lots of ways of converting to local time in human-readable format in any format you want. (As I said, the usual way is to call localtime, then strftime.) But if you want to perform computations, really the only way to do those is using seconds-since-1970 in UTC, because that makes all the other hairy problems go away. How many days are there in the month? Is it a leap year? What time zone are we in? Is daylight saving time in effect?
If you try to represent local time as seconds-since-1970, though, you're probably fibbing. For example, right now, the time is 1460383736, which is 14:08:56 UTC. Where I'm sitting, that's 10:08:56 EDT (U.S. Eastern time, DST in effect). So I suppose I could say that's 1460369336 seconds since 1970, local time. But, again where I'm sitting, 1460369336 seconds ago was not midnight on January 1, 1970 -- it was actually 11 pm on December 31, 1969. It's off by an hour, and the reason is that DST was not in effect on January 1, 1970.
So, bottom line, I would encourage you to rethink the way you're handling local times, because while it's possible to compute this "seconds-since-1970 as local time" value, it's an odd thing to do, and it's likely to cause you various problems which will be much harder to work around than if you used a more straightforward scheme.
But, if you really want to, here are two ways you might be able to determine the offset between UTC and local time, without calling gmtime or _mkgmtime:
Call localtime, and look at the tm_gmtoff field. (Unfortunately, this field is nonstandard, and not present on all systems.)
Call the obsolete ftime function, and look at the timezone field of struct timeb. (Here there are several gotchas: not only is ftime obsolete and nonstandard, but the timezone field is in minutes, and it's positive for zones west of Greenwich, while tm_gmtoff is negative.)
But, anyway, those would more or less directly give you the number to add to or subtract from your UTC seconds-since-1970 value to get "local" seconds-since-1970.
Here is a way to do this computation using the C++11/14 <chrono> library plus this free, open-source timezone library to do the conversion to local time.
#include "tz.h"
#include <iostream>
int
main()
{
using namespace date;
using namespace std;
using namespace std::chrono;
auto now = floor<seconds>(system_clock::now());
auto s = current_zone()->to_local(now) - local_days{1970_y/jan/1};
cout << s.count() << '\n';
}
You first discover your current IANA timezone with current_zone(). Then you get the current time with system_clock::now() and truncate it to seconds. Next you can convert that to your local time, and then subtract the result from any epoch you desire (1970-01-01 in this example).
The result is of type std::chrono::seconds.
All this being said, I share the same reservations about doing this as described in Steve Summit's answer.
If you instead decide to represent the timestamp as a string, that is also easily done:
auto now = make_zoned(current_zone(), floor<seconds>(system_clock::now()));
auto str = format("%F %T %z", now);
str has type std::string. This just output for me:
2016-04-11 11:42:50 -0400
which is my current local time (truncated to seconds), and my current local UTC offset.
If in the future you decide that seconds-precision is too coarse, you can easily change the above code to any other precision by just changing one line:
floor<milliseconds>(system_clock::now());
and now the contents of str would look like:
2016-04-11 11:42:50.368 -0400

time vs gettimeofday c ++

The time command returns the time elapsed in execution of a command.
If I put a "gettimeofday()" at the start of the command call (using system() ), and one at the end of the call, and take a difference, it doesn't come out the same. (its not a very small difference either)
Can anybody explain what is the exact difference between the two usages and which is the best way to time the execution of a call?
Thanks.
The Unix time command measures the whole program execution time, including the time it takes for the system to load your binary and all its libraries, and the time it takes to clean up everything once your program is finished.
On the other hand, gettimeofday can only work inside your program, that is after it has finished loading (for the initial measurement), and before it is cleaned up (for the final measurement).
Which one is best? Depends on what you want to measure... ;)
It's all dependent on what you are timing. If you are trying to time something in seconds, then time() is probably your best bet. If you need higher resolution than that, then I would consider gettimeofday(), which gives up to microsecond resolution (1 / 1000000th of a second).
If you need even higher resolution than that, consider using clock() and CLOCKS_PER_SECOND, just note that clock() is rarely an accurate description for the amount of time taken, but rather the number of CPU cycles used.
time() returns time since epoch in seconds.
gettimeofday(): returns:
struct timeval {
time_t tv_sec; /* seconds */
suseconds_t tv_usec; /* microseconds */
};
Each time function has different precision. In C++11 you would use std::chrono:
using namespace std::chrono;
auto start = high_resolution_clock::now();
/* do stuff*/
auto end = high_resolution_clock::now();
float elapsedSeconds = duration_cast<duration<float>>(end-start).count();

Add two dates in C++

I'm sure this question is answered elsewhere, but I cannot find it on Google or SO, so here goes.
In C/C++, I want to convert a relative time in format dd-hh:mm:ss provided by
ps -o etime
to an absolute UTC formatted date.
This doesn't seem like it should be very hard. Supposing I have already got a function to produce the relative time stored in struct tm format:
struct tm *starting_rel_time = my_reltime_converstion(...);
time_t t = time(0);
struct tm *current_abs_time = localtime(&t);
what I want is basically the opposite of difftime:
struct *tm starting_abs_time = current_abs_time - starting_rel_time;
Now, I can write my own function to do the conversion, but it's a nightmare because of all the carry operations and special conditions (leap years etc.). Surely there is a way to do this in the C/C++ libraries?
Use Boost::Date_Time libraries.
Convert the DD-HH:MM::SS to seconds with simple math; it's relative-time, so just multiply and add. Then, query the current time() in seconds (assuming it's "relative to now"), and add them. Then use gmtime to convert back to a struct tm.
There is no such language as C/C++.
If you're asking about C, I suggest representing dates internally with a simple numeric type, and converting to and from struct tm only when necessary. If you only need to cover a few decades, then you could use time_t and convert using the standard gmtime and mktime library functions. To cover a wider timespan, you could use a Julian day representation.
If you're asking about C++, I suggest the Boost.Date_Time library. Of course, the C library functions are still available if they meet your needs.
What you're trying to do doesn't make sense. You cannot add two dates.
(And difftime doesn't return a date, nor a time_t.)
In practice, on most, if not all implementations, time_t will be an
integral type with the number of seconds since some specific "epoch".
On such machines, you can add or subtract an integral number of seconds
from a time_t to get a new time, at least if all of the times you're
interested in are in the interval supported by time_t (roughly between
1970 and 2038 on most Unix platforms). This, along with gmtime,
mktime and localtime is probably sufficient for your needs. Note
especially that mktime is required to "correct" it's tm input: you
can, for example, take a tm, add 5 to the field tm_mday, call
mktime on it, and get the correct values for a date five days in the
future—all of the necessary carry operations and special
conditions are handled in mktime.
If this is not sufficient, C++11 has both a time_point and a
duration class, with (from a quick glance) seems to have all of the
functionality you could possibly need.

C++11 number of days since date

I need to store date in flat file. Is there any simple metod to get number of days since particular date (for example since 1 AD) using standard libary in C++11? The only one I know is to:
obtain std::tm structure, set all time values to 0
convert it to std::time_t (I do not know proper method yet)
divide time_t to get the resolution of one day
Can I perform it easier?
What you said sounds reasonable to start with. You can convert the struct tm to time_t using mktime. Note that mktime interprets its input as local time according to the system/environment settings, and there is no UTC counterpart that's as widely available without relying on "extra" libraries, but maybe that's not a problem for you.