mktime() like function to produce GMT?

M.-A. Lemburg mal at lemburg.com
Thu May 6 10:06:49 EDT 1999


Mark Nottingham wrote:
> 
> > BTW, any chance of getting the C API timegm() into the time module
> > on those platforms where it is available and have your function
> > as replacement on those that don't ?
> 
> That would be great. Just to flag it, the function Guido posted doesn't take
> two-digit dates into account; rfc822.parsedate() produces two-digit years
> from RFC 850-style dates (amazon.com brought this one up).
> 
> I'm sure there are prettier, faster ways to do this to the code  (BTW,
> assert isn't clearly documented in the reference, AFAIK):
> 
> def timegm(tmtuple):
>     import calendar
>     EPOCH = 1970
>     year, month, day, hour, minute, second = tmtuple[:6]
>     try:
>         assert year >= EPOCH
>     except AssertionError:
>         if year < 69:
>             year = year + 2000
>         else:
>             year = year + 1900
>         assert year >= EPOCH
>     assert 1 <= month <= 12

Note that all these checks are skipped when running Python in
optimized mode (python -O). Better use 'if' instead.

>     days = 365 * (year-EPOCH) + calendar.leapdays(EPOCH, year)
>     for i in range(1, month):
>         days = days + calendar.mdays[i]
>     if month > 2 and calendar.isleap(year):
>         days = days + 1
>     days = days + day - 1
>     hours = days * 24 + hour
>     minutes = hours * 60 + minute

I'm not sure whether introducing Y2K problems in standard lib
functions is such a good idea. The time.mktime() API already
has such a Y2K thingie implemented (much the same as the one
you propose, BTW), which was mainly done to remain backward
compatible -- there's an environment switch called PYTHONY2K
to switch the behaviour off.

It's always better to do such hacks in user code rather than
libraries, e.g. in mxDateTime I provide this API:

def add_century(year,

		current_year=now().year,
		current_century=(now().year / 100) * 100):
    
    """ Sliding window approach to the Y2K problem: adds a suitable
        century to the given year and returns it as integer.

        The window used depends on the current year (at import time).
        If adding the current century to the given year gives a year
        within the range current_year-70...current_year+30 [both
        inclusive], then the current century is added. Otherwise the
        century (current + 1 or - 1) producing the least difference is
        chosen.

    """
    if year > 99:
	# Take it as-is
	return year
    year = year + current_century
    diff = year - current_year
    if diff >= -70 and diff <= 30:
	return year
    elif diff < -70:
	return year + 100
    else:
	return year - 100

This gives the programmer one central place to deal with the
problem. If it should ever become a problem, he can then fix this
one place instead of scanning through all his code... like so
many people are doing now.

-- 
Marc-Andre Lemburg
______________________________________________________________________
Y2000:                                            Y2000: 239 days left
Business:                                      http://www.lemburg.com/
Python Pages:                 http://starship.python.net/crew/lemburg/





More information about the Python-list mailing list