Mailing-List: contact cygwin-help AT cygwin DOT com; run by ezmlm List-Subscribe: List-Archive: List-Post: List-Help: , Sender: cygwin-owner AT cygwin DOT com Mail-Followup-To: cygwin AT cygwin DOT com Delivered-To: mailing list cygwin AT cygwin DOT com From: ericblake AT comcast DOT net (Eric Blake) To: cygwin AT cygwin DOT com Cc: Brian Dessent Subject: Re: strptime error when setting a different TimeZone with export TZ=UTC Date: Fri, 24 Jun 2005 19:45:23 +0000 Message-Id: <062420051945.26249.42BC62D30002FD110000668922007358340A050E040D0C079D0A@comcast.net> X-Authenticated-Sender: ZXJpY2JsYWtlQGNvbWNhc3QubmV0 > Here you call strptime() to fill in the values of 'try', however the > strptime function has the semantics that it will only fill in the > members of struct tm that it is asked to parse. This means that after > the call, some of the members still have undefined values. > Specifically, the members tm_wday, tm_yday, and tm_isdst will contain > garbage. > > > ts2 = mktime(&try) - atoi(timezone)*3600; > > And here you pass this value of 'try' that still has uninitialized > values to mktime(), the result of which will be undefined as well. I > think you were just lucky that it worked in the case where TZ was not > set, but in general once you encounter the situation where you pass > uninitialized data to a function, all bets are off because your program > is invalid C. Not necessarily. According to POSIX, a strptime implementation is allowed (but not necessarily recommended) to set all fields of try, even the ones not related to what was parsed: "It is unspecified whether multiple calls to strptime() using the same tm structure will update the current contents of the structure or overwrite all contents of the structure. Conforming applications should make a single call to strptime() with a format and all data needed to completely specify the date and time being converted." - http://www.opengroup.org/susv3xsh/strptime.html But yes, your advice is also relevant - don't call mktime after strptime unless you are SURE all fields (except tm_wday and tm_yday) have been initialized properly. And pre-initializing to all 0s (as in struct tm try = {0,};) does not work, either, since the rules of state that tm_month must be 1 - 12. In short, struct tm is a nightmare to use, but we are stuck with it for standardized backwards compatibility. -- Eric Blake -- Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple Problem reports: http://cygwin.com/problems.html Documentation: http://cygwin.com/docs.html FAQ: http://cygwin.com/faq/