I am looking for a function in C++ that calculates how many seconds have past from 1/1/1970 until today.
#include <time.h>
time_t seconds_past_epoch = time(0);
Available on most operating systems.
time_t time(void)
time_t time(time_t *ptr)
include: time.h
Returns the number of seconds that have passed since midnight, 1st January 1970 GMT (or pm, 31st December 1969 EST). If the parameter is not NULL, the same value is stored in the location pointed to. Follow this link for information on the time_t type. The value returned may be used as a reliable measure of elapsed time, and may be passed to ctime() or conversion into a human-readable string.
Example:
time_t t1=time(NULL);
do_something_long();
time_t t2=time(NULL);
printf("%d seconds elapsed\n", t2-t1);
time_t values are produced from the clock by time.
time_t values are produced from y,m,d,h,m,s parts by mktime and timegm.
time_t values are analysed into y,m,d,h,m,s by localtime and gmtime.
time_t values are converted to readable strings by ctime.
See man mktime:
#include <time.h>
time_t secsSinceEpoch = mktime(localtime(NULL));
Related
This question is similar to the following:
convert epoch to time_t
Converting time_t to int
but I don't quite have my answer there.
If you want to get the current date/time you can call time(0) or time(NULL) like in the following standard example:
// current date/time based on current system
time_t now = time(0);
I want to define a function which will return a time_t and allows the client to pass an optional default return value in the event of an error. Further, I want to set a default on that "default" argument. This provides symmetry within a library I have with one-to-one counter parts across several languages, so I'm not looking to redesign all that.
My thought was to set the default return to the epoch. Then, a client could in theory easily evaluate that return, and decide that an epoch coming back was more than likely (if not always) an indication of it being invalid. I can think of some alternatives, but nothing clean, that also fits my existing patterns.
Is there a short and sweet way to make my function signature have a default value for this object equal to the epoch? For instance
...myfunc(...., const time_t &defVal=time(0) );
would be perfect if 0 meant the epoch rather than the current date/time!
The function std::time() returns the number of seconds since the epoch as a std::time_t. Therefore to find zero seconds after the epoch set std::time_t to zero:
std::time_t t = 0;
So you could do something like:
void myfunc(const std::time_t& defVal = 0)
What is wrong with using 0? (time_t)0 represents the epoch itself (if you want to find the actual epoch date/time, pass (time_t)0 to gmtime() or localtime()).
time_t myfunc(...., time_t defVal = 0 );
Or, you could use (time_t)-1 instead, which is not a valid time, as time() returns (time_t)-1 on error, and time_t represents a positive number of seconds since the epoch.
time_t myfunc(...., time_t defVal = (time_t)-1 );
Either way provides the user with something that is easily compared, if they don't provide their own default value.
I am processing stored dates and times. I store them in a file in GMT in a string format
(i.e. DDMMYYYYHHMMSS). When a client queries, I convert this string to a struct tm, then convert it to seconds using mktime. I do this to check for invalid DateTime. Again I do convert seconds to string format. All these processing is fine, no issues at all.
But I have one weird issue: I stored the date and time in GMT with locale also GMT. Because of day light saving, my locale time changed to GMT+1. Now, if I query the stored date and time I get 1 hour less because the mktime function uses locale, i.e. GMT+1, to convert the struct tm to seconds (tm_isdst set to -1 so mktime detects daylight savings etc. automatically).
Any ideas how to solve this issue?
Use _mkgmtime/timegm as a complement to mktime.
time_t mkgmtime(struct tm* tm)
{
#if defined(_WIN32)
return _mkgmtime(tm);
#elif defined(linux)
return timegm(tm);
#endif
}
The Daylight Saving Time flag (tm_isdst) is greater than zero if Daylight Saving Time is in effect, zero if Daylight Saving Time is not in effect, and less than zero if the information is not available.
http://www.cplusplus.com/reference/ctime/tm/
Here is the general algorithm:
Pass your input to mktime.
Pass the output to gmtime.
Pass the output to mktime.
And here is a coding example:
struct tm input = Convert(input_string); // don't forget to set 'tm_isdst' here
time_t temp1 = mktime(&input);
struct tm* temp2 = gmtime(&temp1);
time_t output = mktime(temp2);
Note that function gmtime is not thread-safe, as it returns the address of a static struct tm.
I have seconds (say x, x is long long data type) after epoch. I wish to convert it into unix time using <ctime> library. The issue is, I want a time_t variable for gmtime() to work, I am unable to make my x (long long) converted to time_t.
This is what am doing:
//x is number of seconds after epoch, I want that in unix time
time_t t=x;
printf("%s\n",asctime(gmtime(&t)));
Can I somehow typecast x into time_t?
Just cast it?
time_t t = (time_t) x;
It will cut of the top 32 bits but you still have over 25 years until you really need 64-bit timestamps. :)
Of course, there might be trouble if your epoch is not the same as the POSIX epoch (1970-01-01 00:00:00).
Is there some "standard" way or the best I can do is to compute it directly by subtracting from gregorian::date(1970,1,1)?
Since #icecrime's method converts twice (ptime uses linear representation internally), I've decided to use direct computation instead. Here it is:
time_t to_time_t(boost::posix_time::ptime t)
{
using namespace boost::posix_time;
ptime epoch(boost::gregorian::date(1970,1,1));
time_duration::sec_type x = (t - epoch).total_seconds();
// ... check overflow here ...
return time_t(x);
}
EDIT: Thanks #jaaw for bringing this to my attention. Since boost 1.58 this function is included in date_time/posix_time/conversion.hpp, std::time_t to_time_t(ptime pt).
time_t is the type used to hold time in seconds (typically epoch time). I'm guessing you are after epoch time, if so I'm not aware of any way in boost of actually getting epoch time directly, aside from the subtraction you have already. Once you have a time_duration (result of the subtraction), you can call total_seconds() on the duration and store that in time_t.
btw. if you are after epoch time, you could simple use gettimeofday() and save yourself some headache!
Here's a variation of #ybungalobill's method that will get you past 2038, just in case. :)
int64_t rax::ToPosix64(const boost::posix_time::ptime& pt)
{
using namespace boost::posix_time;
static ptime epoch(boost::gregorian::date(1970, 1, 1));
time_duration diff(pt - epoch);
return (diff.ticks() / diff.ticks_per_second());
}
I believe the best you can do is using to_tm to get a tm and mktime to convert the tm to a time_t.
These 2 lines should do it.
tm td_tm = to_tm(pt);
time_t tt = mktime(&td_tm);
What's the best way to convert datetimes between local time and UTC in C/C++?
By "datetime", I mean some time representation that contains date and time-of-day. I'll be happy with time_t, struct tm, or any other representation that makes it possible.
My platform is Linux.
Here's the specific problem I'm trying to solve: I get a pair of values containing a julian date and a number of seconds into the day. Those values are in GMT. I need to convert that to a local-timezone "YYYYMMDDHHMMSS" value. I know how to convert the julian date to Y-M-D, and obviously it is easy to convert seconds into HHMMSS. However, the tricky part is the timezone conversion. I'm sure I can figure out a solution, but I'd prefer to find a "standard" or "well-known" way rather than stumbling around.
A possibly related question is Get Daylight Saving Transition Dates For Time Zones in C
You're supposed to use combinations of gmtime/localtime and timegm/mktime. That should give you the orthogonal tools to do conversions between struct tm and time_t.
For UTC/GMT:
time_t t;
struct tm tm;
struct tm * tmp;
...
t = timegm(&tm);
...
tmp = gmtime(t);
For localtime:
t = mktime(&tm);
...
tmp = localtime(t);
All tzset() does is set the internal timezone variable from the TZ environment variable. I don't think this is supposed to be called more than once.
If you're trying to convert between timezones, you should modify the struct tm's tm_gmtoff.
If on Windows, you don't have timegm() available to you:
struct tm *tptr;
time_t secs, local_secs, gmt_secs;
time( &secs ); // Current time in GMT
// Remember that localtime/gmtime overwrite same location
tptr = localtime( &secs );
local_secs = mktime( tptr );
tptr = gmtime( &secs );
gmt_secs = mktime( tptr );
long diff_secs = long(local_secs - gmt_secs);
or something similar...
If you need to worry about converting date/time with timezone rules, you might want to look into ICU.