web/lib/django/utils/tzinfo.py
changeset 38 77b6da96e6f1
equal deleted inserted replaced
37:8d941af65caf 38:77b6da96e6f1
       
     1 "Implementation of tzinfo classes for use with datetime.datetime."
       
     2 
       
     3 import time
       
     4 from datetime import timedelta, tzinfo
       
     5 from django.utils.encoding import smart_unicode, smart_str, DEFAULT_LOCALE_ENCODING
       
     6 
       
     7 class FixedOffset(tzinfo):
       
     8     "Fixed offset in minutes east from UTC."
       
     9     def __init__(self, offset):
       
    10         if isinstance(offset, timedelta):
       
    11             self.__offset = offset
       
    12             offset = self.__offset.seconds // 60
       
    13         else:
       
    14             self.__offset = timedelta(minutes=offset)
       
    15 
       
    16         sign = offset < 0 and '-' or '+'
       
    17         self.__name = u"%s%02d%02d" % (sign, abs(offset) / 60., abs(offset) % 60)
       
    18 
       
    19     def __repr__(self):
       
    20         return self.__name
       
    21 
       
    22     def utcoffset(self, dt):
       
    23         return self.__offset
       
    24 
       
    25     def tzname(self, dt):
       
    26         return self.__name
       
    27 
       
    28     def dst(self, dt):
       
    29         return timedelta(0)
       
    30 
       
    31 class LocalTimezone(tzinfo):
       
    32     "Proxy timezone information from time module."
       
    33     def __init__(self, dt):
       
    34         tzinfo.__init__(self)
       
    35         self._tzname = self.tzname(dt)
       
    36 
       
    37     def __repr__(self):
       
    38         return smart_str(self._tzname)
       
    39 
       
    40     def utcoffset(self, dt):
       
    41         if self._isdst(dt):
       
    42             return timedelta(seconds=-time.altzone)
       
    43         else:
       
    44             return timedelta(seconds=-time.timezone)
       
    45 
       
    46     def dst(self, dt):
       
    47         if self._isdst(dt):
       
    48             return timedelta(seconds=-time.altzone) - timedelta(seconds=-time.timezone)
       
    49         else:
       
    50             return timedelta(0)
       
    51 
       
    52     def tzname(self, dt):
       
    53         try:
       
    54             return smart_unicode(time.tzname[self._isdst(dt)],
       
    55                                  DEFAULT_LOCALE_ENCODING)
       
    56         except UnicodeDecodeError:
       
    57             return None
       
    58 
       
    59     def _isdst(self, dt):
       
    60         tt = (dt.year, dt.month, dt.day, dt.hour, dt.minute, dt.second, dt.weekday(), 0, -1)
       
    61         try:
       
    62             stamp = time.mktime(tt)
       
    63         except (OverflowError, ValueError):
       
    64             # 32 bit systems can't handle dates after Jan 2038, and certain
       
    65             # systems can't handle dates before ~1901-12-01:
       
    66             #
       
    67             # >>> time.mktime((1900, 1, 13, 0, 0, 0, 0, 0, 0))
       
    68             # OverflowError: mktime argument out of range
       
    69             # >>> time.mktime((1850, 1, 13, 0, 0, 0, 0, 0, 0))
       
    70             # ValueError: year out of range
       
    71             #
       
    72             # In this case, we fake the date, because we only care about the
       
    73             # DST flag.
       
    74             tt = (2037,) + tt[1:]
       
    75             stamp = time.mktime(tt)
       
    76         tt = time.localtime(stamp)
       
    77         return tt.tm_isdst > 0