Pergunta
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?
Solução
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
.
Outras dicas
Use Boost::Date_Time libraries.
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.