Reading local time into time_t

H

Henrik Goldman

I have strings like "2006-03-26 21.51" which I would like to convert into
time_t. I know that the string is in localtime.

So far I've written the following code:

time_t LocalTimeFromString(string str)
{
struct tm t;
memset(&t, 0, sizeof(t));

if (str.length() != 16)
return 0;

sscanf(str.c_str(), "%04d-%02d-%02d %02d:%02d",
&t.tm_year, &t.tm_mon, &t.tm_mday, &t.tm_hour, &t.tm_min);

t.tm_year -= 1900;
t.tm_mon -= 1;

return mktime(&t);
}

However it seems that time_t must be in UTC time. If I would use ctime() on
the time_t result I don't get the right result back.

How would I go about adjusting the result for localtime? The solution must
be platform independent since it's suppose to work on both Unix and Windows.

Thanks in advance.

-- Henrik
 
A

AnonMail2005

Henrik said:
I have strings like "2006-03-26 21.51" which I would like to convert into
time_t. I know that the string is in localtime.

So far I've written the following code:

time_t LocalTimeFromString(string str)
{
struct tm t;
memset(&t, 0, sizeof(t));

if (str.length() != 16)
return 0;

sscanf(str.c_str(), "%04d-%02d-%02d %02d:%02d",
&t.tm_year, &t.tm_mon, &t.tm_mday, &t.tm_hour, &t.tm_min);

t.tm_year -= 1900;
t.tm_mon -= 1;

return mktime(&t);
}

However it seems that time_t must be in UTC time. If I would use ctime() on
the time_t result I don't get the right result back.

How would I go about adjusting the result for localtime? The solution must
be platform independent since it's suppose to work on both Unix and Windows.

Thanks in advance.

-- Henrik
Check out the date/time library from boost to do this.

It's one thing to do this as a learning excercise but since you say it
needs to be platform independent I suspect that this is not a learning
project.
 
H

Henrik Goldman

Check out the date/time library from boost to do this.

Thanks for the suggestion but unfortunatly not usable in my case. Since it's
a library that I write I cannot put boost into it. There are too many
requirements and obstacles to make this into a solution, unfortunatly.
It's one thing to do this as a learning excercise but since you say it
needs to be platform independent I suspect that this is not a learning
project.

True. I guess it should be possible to solve by looking at the environment
variables for daylight adjustment and timezone but I doubt I'm the first one
to have come into this problem. Therefore I thought someone else could
perhaps point me to a website that shows such a solution.

Thanks in advance.
-- Henrik
 
A

AnonMail2005

Henrik said:
Thanks for the suggestion but unfortunatly not usable in my case. Since it's
a library that I write I cannot put boost into it. There are too many
requirements and obstacles to make this into a solution, unfortunatly.


True. I guess it should be possible to solve by looking at the environment
variables for daylight adjustment and timezone but I doubt I'm the first one
to have come into this problem. Therefore I thought someone else could
perhaps point me to a website that shows such a solution.

Thanks in advance.
-- Henrik
Why can't you "put" boost into a library you write? Who or what
is putting this constraint on you?
 
A

AnonMail2005

Henrik said:
I have strings like "2006-03-26 21.51" which I would like to convert into
time_t. I know that the string is in localtime.

So far I've written the following code:

time_t LocalTimeFromString(string str)
{
struct tm t;
memset(&t, 0, sizeof(t));

if (str.length() != 16)
return 0;

sscanf(str.c_str(), "%04d-%02d-%02d %02d:%02d",
&t.tm_year, &t.tm_mon, &t.tm_mday, &t.tm_hour, &t.tm_min);

t.tm_year -= 1900;
t.tm_mon -= 1;

return mktime(&t);
}

However it seems that time_t must be in UTC time. If I would use ctime() on
the time_t result I don't get the right result back.

How would I go about adjusting the result for localtime? The solution must
be platform independent since it's suppose to work on both Unix and Windows.

Thanks in advance.

-- Henrik
A quick look at the various time functions yields this algorithm:

Just adjust your time_t result returned from mktime() by the time
difference between local and UTC time. This difference is fixed except
when you cross into (or out of) daylight savings time.

You can get the UTC time and local time using gmtime() and
localtime() functions (both convert time_t into struct tm). Now use
mktime() function to convert these struct tms into time_ts. And then
use difftime() to get the actual difference. You should be able to use
this difference to adjust your time_t values.
 
H

Henrik Goldman

You can get the UTC time and local time using gmtime() and
localtime() functions (both convert time_t into struct tm). Now use
mktime() function to convert these struct tms into time_ts. And then
use difftime() to get the actual difference. You should be able to use
this difference to adjust your time_t values.

Thanks. This sounds like a good idea. Which time do you suggest I should use
those first functions on? I guess I should use the un-adjusted time_t,
right?

Thanks.
-- Henrik
 
H

Henrik Goldman

Why can't you "put" boost into a library you write? Who or what
is putting this constraint on you?

It's a static library that I'm creating. In other words it's linked at the
client site together with code that I have no control over.
This means if they use boost as well then there will eventually be trouble
(unless I would rename the namespace so I get my own "version" of boost).
Besides this it adds extra code in there which is not a good idea (esp.
since it's planned to be ported to embedded OS's in future). Last but not
least it makes it harder to port the code for new compilers. I will only be
able to compile my code if boost supports the platform. I don't say it's a
realistic problem since I know they do alot of platform support, but still
it's something that I need to worry about.

Those requirements are what users expect of my library, not my own ideas.

-- Henrik
 
R

red floyd

Henrik said:
Thanks. This sounds like a good idea. Which time do you suggest I should use
those first functions on? I guess I should use the un-adjusted time_t,
right?

I went through this mess a couple of years ago.
You have to make the calls to localtime and gmtime every time, though.

Consider if you take the time differential at the start of your program,
and during your run, daylight savings time starts or ends (possible if
you have a program designed to run for days at a time). Then your time
differential is incorrect after a while. So you need to perform get the
local and gmtime every time you wish to convert a time_t struct. I
personally believe that there should have been a mkgmtime() as the
inverse of gmtime().
 
M

Marcus Kwok

red floyd said:
Consider if you take the time differential at the start of your program,
and during your run, daylight savings time starts or ends (possible if
you have a program designed to run for days at a time). Then your time
differential is incorrect after a while. So you need to perform get the
local and gmtime every time you wish to convert a time_t struct.

I'm not sure if DST is standardized, but if it is, you could cache the
value and only update if you see a date that is across the DST status
change.

Well, I just checked and a struct tm does have a field tm_isdst, so
maybe this could be queried to see if you need to update the correction
factor.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,483
Members
44,901
Latest member
Noble71S45

Latest Threads

Top