app/django/utils/tzinfo.py
author Sverre Rabbelier <srabbelier@gmail.com>
Mon, 10 Nov 2008 00:41:01 +0000
changeset 458 e836e8914c8e
parent 323 ff1a9aa48cfd
permissions -rw-r--r--
Added support for providing a custom params dict This has been a long outstanding feature request for tlarsen, luckily it turned out to be very easy to implement with the dict.merge utility method. To have custom _rights one should instead to the required access checks before calling the view method.

"Implementation of tzinfo classes for use with datetime.datetime."

import locale
import time
from datetime import timedelta, tzinfo
from django.utils.encoding import smart_unicode

try:
    DEFAULT_ENCODING = locale.getdefaultlocale()[1] or 'ascii'
except:
    # Any problems at all determining the locale and we fallback. See #5846.
    DEFAULT_ENCODING = 'ascii'

class FixedOffset(tzinfo):
    "Fixed offset in minutes east from UTC."
    def __init__(self, offset):
        if isinstance(offset, timedelta):
            self.__offset = offset
            offset = self.__offset.seconds // 60
        else:
            self.__offset = timedelta(minutes=offset)

        self.__name = u"%+03d%02d" % (offset / 60, offset % 60)

    def __repr__(self):
        return self.__name

    def utcoffset(self, dt):
        return self.__offset

    def tzname(self, dt):
        return self.__name

    def dst(self, dt):
        return timedelta(0)

class LocalTimezone(tzinfo):
    "Proxy timezone information from time module."
    def __init__(self, dt):
        tzinfo.__init__(self)
        self._tzname = self.tzname(dt)

    def __repr__(self):
        return self._tzname

    def utcoffset(self, dt):
        if self._isdst(dt):
            return timedelta(seconds=-time.altzone)
        else:
            return timedelta(seconds=-time.timezone)

    def dst(self, dt):
        if self._isdst(dt):
            return timedelta(seconds=-time.altzone) - timedelta(seconds=-time.timezone)
        else:
            return timedelta(0)

    def tzname(self, dt):
        try:
            return smart_unicode(time.tzname[self._isdst(dt)], DEFAULT_ENCODING)
        except UnicodeDecodeError:
            return None

    def _isdst(self, dt):
        tt = (dt.year, dt.month, dt.day, dt.hour, dt.minute, dt.second, dt.weekday(), 0, -1)
        try:
            stamp = time.mktime(tt)
        except (OverflowError, ValueError):
            # 32 bit systems can't handle dates after Jan 2038, and certain
            # systems can't handle dates before ~1901-12-01:
            #
            # >>> time.mktime((1900, 1, 13, 0, 0, 0, 0, 0, 0))
            # OverflowError: mktime argument out of range
            # >>> time.mktime((1850, 1, 13, 0, 0, 0, 0, 0, 0))
            # ValueError: year out of range
            #
            # In this case, we fake the date, because we only care about the
            # DST flag.
            tt = (2037,) + tt[1:]
            stamp = time.mktime(tt)
        tt = time.localtime(stamp)
        return tt.tm_isdst > 0