UNIX Socket FAQ

A forum for questions and answers about network programming on Linux and all other Unix-like systems

You are not logged in.

  • Index
  • » C++
  • » C++ time to string and vice versa, bug in gnu mktime?

#1 2004-11-05 02:24 PM

Nope
Administrator
From: Germany
Registered: 2004-01-24
Posts: 385
Website

Re: C++ time to string and vice versa, bug in gnu mktime?

System SuSE Linux 9.1 (kernel 2.6)
gnu C++ 3.3.3


Ok. I encountered a bizare problem. In my www server I create a header field called "Last-Modified: " and browsers use that to send a "If-Modified-Since: " later to prevent getting the whole file again if it's still in their cache.

----------------------------------------------------------------------------

In reality it looks like this:
In the response header (server to browser):
Last-Modified: Wed, 13 Oct 2004 15:38:26 GMT

In the request header (browser to server):
If-Modified-Since: Wed, 13 Oct 2004 15:38:26 GMT

----------------------------------------------------------------------------

Now the funny part. A week ago, when I tested that last, this condition was recogniced as identical. Now the function returns a difference of 1 hour (3600sec). The only difference is that we had a change in day saving time (german Sommerzeit has ended).

I used this code to check if I made an error:


struct tm tmstruct;
	time_t act;

	memset(&tmstruct,0,sizeof(struct tm));
	act=time(0);
	cout<<"act: "<<act<<" - ";

	gmtime_r(&act,&tmstruct);
	strftime(temp,100,"%a, %d %b %Y %H:%M:%S %Z",&tmstruct);
	memset(&tmstruct,0,sizeof(struct tm));
	strptime(temp,"%a, %d %b %Y %H:%M:%S %Z",&tmstruct);
	act=mktime(&tmstruct);
	cout<<"erg: "<<act<<endl;

   

The result: "act: 1099658690 - erg: 1099655090"
You see, a difference of 3600.

Now I specify corectly the timezone as GMT in both cases (%Z), so it should normally deliver the right value, shouldn't it?


Now, do I make an error, is that an error in my gnu or is there something wrong with my Linux? I am a bit lost on this one.
-------------------------------------------------------------------------------------
Edited:

The problem already occures if I just do that:

struct tm tmstruct;
	memset(&tmstruct,0,sizeof(struct tm));
	time_t act=time(0);
	cout<<"act: "<<act<<" - ";
	gmtime_r(&act,&tmstruct);
	act=mktime(&tmstruct);
	cout<<"erg: "<<act<<endl;

So either I have misunderstood the functionality of mktime or something outside my code is not working ok...

Offline

#2 2004-11-05 05:59 PM

i3839
Oddministrator
From: Amsterdam
Registered: 2003-06-07
Posts: 2,239

Re: C++ time to string and vice versa, bug in gnu mktime?

What is your system timezone? Because it looks like you're converting the system time to GMT. If you have a correct local time then it's expected that the GMT+1 when converted to GMT gives a time one hour less than the local time. I guess I'm missing the problem though...

Offline

#3 2004-11-05 10:17 PM

RobSeace
Administrator
From: Boston, MA
Registered: 2002-06-12
Posts: 3,839
Website

Re: C++ time to string and vice versa, bug in gnu mktime?

Yeah, your problem is that mktime() expects to work off of a
struct tm in your LOCAL timezone, NOT a GMT/UTC filled one...
Ie: it only works properly if you filled the struct tm via localtime()
or localtime_r(), not gmtime()/gmtime_r()...

The function you want (which may not be entirely standard) is
timegm() instead of mktime()...

Offline

#4 2004-11-06 03:16 AM

Nope
Administrator
From: Germany
Registered: 2004-01-24
Posts: 385
Website

Re: C++ time to string and vice versa, bug in gnu mktime?

Yep i3839, you kinda miss the point. I know it's a timezone problem. I did
think that mktime was supposed to use the computers timezone info to
counter that. I am also not sure if it doesn't perhaps even do that. It
worked fine last week after all and I didn't change my settings. We had a
change due to the end of the daylight saving time though which is also
3600 seconds.

It's still odd. I've read the man pages again and Rob is right, mktime
ignores the local settings, just directly translates the given time based on
the struct, while I on the other hand translate the local time to UTC (or
GMT or whatever you want to call it) before use. So that it worked before
was pure chance.

So, what I do now is getting the right offset values in my configuration
routine by calling localtime_r once and store the offset value for the
timezone, adding that later manually. Or perhaps there is a way to set
the timezone to gmt for the program in the first place?

I do kinda wonder though why there isn't a complete function set to work
with GMT. It's a bit odd to only have half the needed things in a library this
old.

Offline

#5 2004-11-06 08:49 AM

Nope
Administrator
From: Germany
Registered: 2004-01-24
Posts: 385
Website

Re: C++ time to string and vice versa, bug in gnu mktime?

:( Still not working. It is this darn daylight saving time after all.

A date of 13th Dec doesn't work, but with 6th Oct it does, regardless of year and exact time.

I do kinda hate it. The other server apps I tested on my computer don't make this mistake though, so they do something different here. That also rules a OS problem out, nailing the problem to my code.

Offline

#6 2004-11-06 06:03 PM

Nope
Administrator
From: Germany
Registered: 2004-01-24
Posts: 385
Website

Re: C++ time to string and vice versa, bug in gnu mktime?

In case someone wants to know, I've re-written that part of my code. I changed some lines and now directly work with the date strings. It's actually faster this way as I had to create the string version anyway a bit later. It's still annoying.

Offline

#7 2004-11-06 08:06 PM

RobSeace
Administrator
From: Boston, MA
Registered: 2002-06-12
Posts: 3,839
Website

Re: C++ time to string and vice versa, bug in gnu mktime?

Offline

#8 2004-11-07 04:46 AM

Nope
Administrator
From: Germany
Registered: 2004-01-24
Posts: 385
Website

Re: C++ time to string and vice versa, bug in gnu mktime?

Well, I use actually a lot non-portable stuff in one of my wwwservers, so here it wouldn't make much of a difference. But I try to keep the shared code parts (my libraries so to speak) clean for later use.

I did think about using the tzset command to just set the timezone to GMT for the whole app, but then all my "shared" timestamps would have been wrong again.

In the end I found a way that works and is fast in this special case, allthough I have to actually compare the strings to see which time is sooner of the 2. But the strict definition of the timestring makes that pretty straight forward for most of it, only the month is there in its word form and has to be parsed seperately.

Offline

  • Index
  • » C++
  • » C++ time to string and vice versa, bug in gnu mktime?

Board footer

Powered by FluxBB