Converting localtime to time_t (C++) - c++

I creating date() function on C++ http://aliarth.lt/date.cpp and I got one problem with localtome_to_time() conversion. Does anyone know how that local_time variable:
int time_integer = 12345;
time_t time = (time_t)time_integer;
tm *local_time = localtime(&time);
local_time->tm_year = 100;
local_time->tm_mon = 10;
local_time->tm_mday = 1;
Convert to time_t?

Try mktime, here is its signature:
time_t mktime (struct tm * timeptr);
Returns the value of type time_t that represents the local time described by the tm structure pointed by timeptr (which may be modified).

Related

COleDateTime adding an hour when constructed with time_t

I have a struct tm object that is converted to UNIX time_t using mktime, that when passed into the constructor of COleDateTime seems to be adding an hour to account for daylight savings (UK time), even though the documentation for COleDateTime suggests that it ignores DST.
If I create my time with SYSTEMTIME and pass that object to COleDateTime the problem disappears. Does anyone have any idea why this might be happening? This is from legacy code so changing everything to SYSTEMTIME may not be a solution.
Here is my example code:
timeinfo.tm_year = 2018 - 1900;
timeinfo.tm_mon = 6 - 1;
timeinfo.tm_mday = 1;
timeinfo.tm_isdst = 0;
timeinfo.tm_hour = 10;
timeinfo.tm_min = 30;
timeinfo.tm_sec = 40;
auto unix = mktime( &timeinfo );
printf("UNIX time %lld\n", unix);
COleDateTime date(unix);
printf("COleDateTime: %f\n", date.m_dt);
CString res = date.Format();
printf("Formatted: %ls\n", res.GetString());
Answered my own question:
COleDateTime time_t constructor uses CTime internally which, regardless of what the documentation for COleDateTime says, does take into account the environment variables for locale and timezone.

Strange behaviour of localtime function

I am trying to subtract 7 days from current date and send them to a function. My code is:
time_t startTime;
time_t endTime;
struct tm *startDate;
struct tm *endDate;
time(&endTime);
endDate = localtime(&endTime); //here endDate becomes 26-05-2015
startTime = endTime - 24 * 60 * 60 * 7;
startDate = localtime(&startTime);
however after this both endDate and startDate becomes 19-05-2015
Where I am going wrong?
The localtime is allowed to use an internal (static) buffer for the string, meaning you need to copy the string returned, or use localtime_s instead.
The std::localtime() function returns a pointer to a static struct so it returns the same address each time.
You can make a copy of the return from std::localtime() like this:
#include <ctime>
int main()
{
time_t startTime;
time_t endTime;
// don't use pointers
std::tm startDate;
std::tm endDate;
time(&endTime);
// dereference the return value (with *) to make a copy
endDate = *std::localtime(&endTime);
startTime = endTime - 24 * 60 * 60 * 7;
startDate = *std::localtime(&startTime);
}
They are both pointers to the same structure. Declare your own struct tm variables and copy what the localtime() return value points to:
struct tm startDate, endDate;
....
endDate = * localtime(&endTime);
....
startDate = * localtime(&startTime);

Getting time difference using a time_t converted from a string

I am trying to get the diff between two dates.
One date being right now and the other is a date converted to time_t from a string representation of a date.
My code is as follows
const char *time_details = "12/03/2014";
struct tm tm;
strptime(time_details, "%m/%d/%Y", &tm);
time_t mytime = mktime(&tm);
time_t now;
time(&now);
double seconds = difftime(now, mytime);
LOGG("now = %d", now);
LOGG("mytime = %d", mytime);
LOGG("unsigned int mytime = %d", (int)mytime);
My output looks like so:
now = 1417830679
mytime = -1
seconds = 1610001720
mytime always comes out to -1
And, the value for seconds is not correct either.
Add before use (and you might want to pick a different name for the variable)
memset(&tm, 0, sizeof(struct tm));
See Notes section in strptime(3)

Convert a time (UTC ) given as a string to local time

I have a time string like this "132233" (Time only no date) and i want to convert it into local time.
So, in order to use the function localtime(), I first converted my string into time_t using mktime() (thanks to How to convert a string variable containing time to time_t type in c++? )and then printed the time after conversion using strftime as shown in (http://www.cplusplus.com/reference/ctime/strftime/)
I am getting a serious run time error. Can any one please tell me whats wrong. Thanks in advance
int main()
{
string time_sample="132233";
std::string s_hrs (time_sample.begin(), time_sample.begin()+2);
std::string s_mins (time_sample.begin()+2,time_sample.begin()+4);
std::string s_secs (time_sample.begin()+4,time_sample.begin()+6);
int hrs = atoi(s_hrs.c_str());
int mins = atoi(s_mins.c_str());
int secs = atoi(s_secs.c_str());
struct tm time_sample_struct = {0};
time_sample_struct.tm_hour = hrs;
time_sample_struct.tm_min = mins;
time_sample_struct.tm_sec = secs;
time_t converted_time;
converted_time = mktime(&time_sample_struct);
struct tm * timeinfo;
char buffer[80];
timeinfo = localtime(&converted_time);
strftime(buffer,80,"%I:%M:%S",timeinfo);
puts(buffer);
cout<<endl;
getch();
return 0;
}
Your problem is that if time_t is a 32 bit value, the earliest possible date it's capable of encoding (given a 1970-1-1 epoch) is 1901-12-13.
However you're not setting the date fields of your tm struct, which means it is defaulting to 0-0-0 which represents 1900-1-0 (since tm_day is 1-based, you actually end up with an invalid day-of-month).
Since this isn't representable by a 32-bit time_t the mktime function is failing and returning -1, a situation you're not checking for.
Simplest fix is to initialise the date fields of the tm struct to something a time_t can represent:
time_sample_struct.tm_year = 114;
time_sample_struct.tm_mday = 1;

difference seen in difftime and strftime values

I'm seeing a difference in time functions and was wondering what was the reason.
currently, I'm using localtime, mktime, strftime and difftime:
time_t ltime;
ltime = time(NULL);
StartTM = localtime(&ltime);
time_t time1 = mktime(StartTM );
char startbuffer [128];
strftime( start_buffer, 128, "%H:%M:%S", StartTM );
<<Do some stuff, take some time >>>
time_t ttime;
ttime = time(NULL);
StopTM = localtime(&ttime);
time_t time2 = mktime(StopTM );
char stop_buffer [128];
strftime( stop_buffer, 128, "%H:%M:%S:", StopTM );
double wtinsec = difftime(time2, time1);
Executed, the output looks like this:
Stop buffer=08:46:18
Start buffer=08:44:11
wtinsec=129
Subtracting start from stop by hand, the length of time is 2:07, however the total number of seconds (difftime) says 2:09. As both times are using the same raw data (time1, time2) for both calculations, my initial thoughts was combination of lack of precision in the strftime conversion and difftime is the cause of this.
But the difference is not constant. If the time between the 2 local calls is small (like 10 seconds) there is no difference. However, as the time between the 2 time calls gets longer, the difference in time totals becomes larger. At 2 mins, its 2 seconds at 5 mins its 4 seconds and so on...
Any reason why this is happening and is there anything more accurate (in C++) preferably in micro/milliseconds that can track time of day and subtract one from another?
Thanks.
The values in ltime and time1 should be identical; the round trip through localtime() and mktime() should give you the answer you started with. Similarly, of course, for ttime and time2.
This C code demonstrates the expected behaviour. You need to look hard at your code to find out what is going wrong.
#include <stdio.h>
#include <time.h>
#include <unistd.h>
int main(void)
{
time_t ltime = time(NULL);
struct tm *start = localtime(&ltime);
time_t time1 = mktime(start);
char startbuffer[128];
strftime(startbuffer, sizeof(startbuffer), "%H:%M:%S", start);
printf("lt = %10lu, t1 = %10lu, time = %s\n",
(unsigned long)ltime, (unsigned long)time1, startbuffer);
sleep(10);
time_t ttime = time(NULL);
struct tm *finis = localtime(&ttime);
time_t time2 = mktime(finis);
strftime(startbuffer, sizeof(startbuffer), "%H:%M:%S", finis);
printf("lt = %10lu, t1 = %10lu, time = %s\n",
(unsigned long)ttime, (unsigned long)time2, startbuffer);
printf("diff time = %.2f\n", difftime(time2, time1));
return(0);
}
Sample output (from Mac OS X 10.7.5):
lt = 1358284665, t1 = 1358284665, time = 13:17:45
lt = 1358284675, t1 = 1358284675, time = 13:17:55
diff time = 10.00
I recommend looking at the values in your code, similar to the way I did. You might (or might not) print out the contents of the struct tm structures. It would be worth making a function to handle the 7-line block of repeated code; you'll need it to return time1 and time2, of course, so you can do the difference in the 'main' code. Also remember that localtime() may return the same pointer twice; you can't reliably use the start time structure after you've called localtime() with the finish time.