> 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 <time.h> 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/