[Python-Dev] zipimport, round 3 (or would that be that 37?)

Fredrik Lundh fredrik@pythonware.com
Mon, 9 Dec 2002 16:37:37 +0100


just wrote:

> > Looking at the code in zipfile.py which converts a time tuple to DOS date
> > and time shorts (I didn't see code that went the other way), it appears that
> > dosdate is 7 bits for the year, 4 bits for the month and 5 bits for the day.
> > Dostime looks like 5 bits for the hour, 6 bits for the minute and 5 bits for
> > half the number of seconds.  You should be able to extract those chunks into
> > a tm structure then call the C lib mktime() function to convert to a time in
> > seconds since the epoch (this is just off the top of my head):
> > 
> >     stm = malloc(sizeof(struct tm));
> >     stm->tm_sec = (dostime & 0x1f) * 2;
> >     stm->tm_min = (dostime >> 5) & 0x3f;
> >     stm->tm_hour = dostime >> 11);
> >     stm->tm_mday = dosdate & 0x1f;
> >     stm->tm_mon = (dosdate >> 5) & 0xf;
> >     stm->tm_year = dosdate >> 9;

I could have sworn zip files stored UTC time, but the specification
only says "time", and zipfile.py uses localtime.  oh well...  here's a
slightly more robust (but still untested) version:

        #include <time.h>

        struct tm stm;
        time_t mtime;

        stm.tm_sec = (dostime & 0x1f) * 2;
        stm.tm_min = (dostime >> 5) & 0x3f;
        stm.tm_hour = (dostime >> 11) & 0x1f;
        stm.tm_mday = dosdate & 0x1f;
        stm.tm_mon = ((dosdate >> 5) & 0xf) - 1;
        stm.tm_year = ((dosdate >> 9) & 0x7f) + 80;
        stm.tm_isdst = 0; /* wday/yday is ignored */

        mtime = mktime(&stm);

you may have to add 1 to the mday (mktime expects 1..31) and/or
remove the -1 from the mon value (mktime expects 0..11).

> Thanks! How portable is this? Which header(s) should I include?

mktime is part of ANSI C.  for the header, see above.

</F>