Author Stephen.White
Recipients Stephen.White, belopolsky, brett.cannon, brian.curtin, grantbow, jonsiddle, loewis, pboddie, quale, r.david.murray, rhettinger
Date 2011-06-14.16:03:36
SpamBayes Score 2.9976e-15
Marked as misclassified No
Message-id <1308067417.39.0.618178450839.issue762963@psf.upfronthosting.co.za>
In-reply-to
Content
The patch, issue762963.diff, is broken.  It is calling mktime on a struct tm that is initialized to zeros.  This means that it should be filling in the missing fields based on their correct values for the date 1st Jan 1900, which is incorrect behaviour as the whole method should be choosing appropriate values based on the date provided by the user.

However in practice this call to mktime is effectively a no-op on 32bit systems.  The reason for this is:

The mktime(p) call is at the top of the method, straight after the memset(p, '\0', ...) call.  This means p->tm_year is zero.  According to the definition of struct tm a zero in the year field means 1900.

On a 32bit system the earliest date handled by libc is 2**31 seconds before the Epoch (1st Jan 1970);
>>> time.strftime("%Y-%m-%d %H:%M:%S %Z", time.localtime(-2**31))'1901-12-13 20:45:52 GMT'

So dates in the year 1900 cannot be handled by libc, and in this situation the mktime(p) call makes no attempt to normalise the provided data (or fill in missing values).

The situation is different on 64bit systems.  Here there is no problem with a much wider range of dates.  This means that dates during 1900 *are* handled by libc, and so it does attempt to normalise the data and fill in missing values.

For most of the fields in the structure whether or not mktime fills in or alters their value is of little consequence, as they're immediately overwritten by the call to PyArg_Parse.  However the contents of the tm_gmtoff & tm_zone fields are not overwritten.

If the mktime call does nothing (as on a 32bit system) then tm_zone remains NULL throughout.

If the mktime call does fill in missing values (as on 64bit systems) then tm_zone is set to the appropriate timezone for the zero time (the beginning of the year 1900).  In our case this is always "GMT", because the beginning of the year is in winter (when we use GMT).

If tm_zone is set when the structure is passed into strftime then it is honoured.  So if it has been set by mktime to be GMT then strftime will output GMT, regardless of the correct timezone string for the actual time provided.
History
Date User Action Args
2011-06-14 16:03:37Stephen.Whitesetrecipients: + Stephen.White, loewis, brett.cannon, rhettinger, pboddie, belopolsky, quale, r.david.murray, brian.curtin, grantbow, jonsiddle
2011-06-14 16:03:37Stephen.Whitesetmessageid: <1308067417.39.0.618178450839.issue762963@psf.upfronthosting.co.za>
2011-06-14 16:03:36Stephen.Whitelinkissue762963 messages
2011-06-14 16:03:36Stephen.Whitecreate