Ticket #479: timezone.2.patch

File timezone.2.patch, 6.6 KB (added by sune.kirkeby@…, 9 years ago)

Bugfix update of previous patch

  • django/utils/tzinfo.py

     
     1"""Implementation of a tzinfo-classes for use with datetime.datetime."""
     2
     3import time
     4from datetime import timedelta, tzinfo
     5
     6ZERO = timedelta(0)
     7STDOFFSET = timedelta(seconds=-time.timezone)
     8DSTOFFSET = timedelta(seconds=-time.altzone)
     9DSTDIFF = DSTOFFSET - STDOFFSET
     10
     11class FixedOffset(tzinfo):
     12    """Fixed offset in minutes east from UTC."""
     13
     14    def __init__(self, offset):
     15        self.__offset = timedelta(minutes=offset)
     16        # FIXME -- Not really a name...
     17        self.__name = "%+03d%02d" % (offset / 60, offset % 60)
     18
     19    def utcoffset(self, dt):
     20        return self.__offset
     21
     22    def tzname(self, dt):
     23        return self.__name
     24
     25    def dst(self, dt):
     26        return ZERO
     27
     28class LocalTimezone(tzinfo):
     29    """Proxy timezone information from time module."""
     30
     31    def utcoffset(self, dt):
     32        if self._isdst(dt):
     33            return DSTOFFSET
     34        else:
     35            return STDOFFSET
     36
     37    def dst(self, dt):
     38        if self._isdst(dt):
     39            return DSTDIFF
     40        else:
     41            return ZERO
     42
     43    def tzname(self, dt):
     44        return time.tzname[self._isdst(dt)]
     45
     46    def _isdst(self, dt):
     47        tt = (dt.year, dt.month, dt.day,
     48              dt.hour, dt.minute, dt.second,
     49              dt.weekday(), 0, -1)
     50        stamp = time.mktime(tt)
     51        tt = time.localtime(stamp)
     52        return tt.tm_isdst > 0
  • django/utils/dateformat.py

     
    1111>>>
    1212"""
    1313
     14# FIXME -- Try this in a template and weep
     15#   { now:"\T\h\i\s \i\s \e\s\c\a\p\e\d" }
     16# or
     17#   { now:"\\T\\h\\i\\s \\i\\s \\e\\s\\c\\a\\p\\e\\d" }
     18
    1419from calendar import isleap
    1520from dates import MONTHS, MONTHS_AP, WEEKDAYS
     21from tzinfo import LocalTimezone
    1622
    1723class DateFormat:
    1824    year_days = [None, 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334]
     
    2026    def __init__(self, d):
    2127        self.date = d
    2228
     29        self.timezone = getattr(self.date, 'tzinfo', None)
     30        if not self.timezone:
     31            self.timezone = LocalTimezone(self.date)
     32
    2333    def a(self):
    2434        "'a.m.' or 'p.m.'"
    2535        if self.date.hour > 11:
     
    8494
    8595    def I(self):
    8696        "'1' if Daylight Savings Time, '0' otherwise."
    87         raise NotImplementedError
     97        return self.timezone.dst()
    8898
    8999    def j(self):
    90100        "Day of the month without leading zeros; i.e. '1' to '31'"
     
    116126
    117127    def O(self):
    118128        "Difference to Greenwich time in hours; e.g. '+0200'"
    119         raise NotImplementedError
     129        tz = self.timezone.utcoffset(self.date)
     130        return "%+03d%02d" % (tz.seconds / 3600, (tz.seconds / 60) % 60)
    120131
    121132    def P(self):
    122133        """
     
    158169
    159170    def T(self):
    160171        "Time zone of this machine; e.g. 'EST' or 'MDT'"
    161         raise NotImplementedError
     172        return self.timezone.tzname(self.date)
    162173
    163174    def U(self):
    164175        "Seconds since the Unix epoch (January 1 1970 00:00:00 GMT)"
     
    216227        """Time zone offset in seconds (i.e. '-43200' to '43200'). The offset
    217228        for timezones west of UTC is always negative, and for those east of UTC
    218229        is always positive."""
    219         raise NotImplementedError
     230        return self.timezone.utcoffset(self.date).seconds
    220231
    221232    def format(self, formatstr):
    222233        result = ''
    223234        for char in formatstr:
    224             try:
     235            if hasattr(self, char):
    225236                result += str(getattr(self, char)())
    226             except AttributeError:
     237            else:
    227238                result += char
    228239        return result
    229240
  • django/core/db/typecasts.py

     
    11import datetime
     2from django.utils.tzinfo import FixedOffset
    23
    34###############################################
    45# Converters from database (string) to Python #
     
    1617        microseconds = '0'
    1718    return datetime.time(int(hour), int(minutes), int(seconds), int(float('.'+microseconds) * 1000000))
    1819
     20def parse_tz(tz):
     21    if ':' in tz:
     22        h, m = tz.split(':')
     23    else:
     24        h, m = tz, '0'
     25    return int(h) * 60 + int(m)
    1926def typecast_timestamp(s): # does NOT store time zone information
    2027    # "2005-07-29 15:48:00.590358-05"
    2128    # "2005-07-29 09:56:00-05"
     
    2532    # it away, but in the future we may make use of it.
    2633    if '-' in t:
    2734        t, tz = t.split('-', 1)
    28         tz = '-' + tz
     35        tz = - parse_tz(tz)
    2936    elif '+' in t:
    3037        t, tz = t.split('+', 1)
    31         tz = '+' + tz
     38        tz = parse_tz(tz)
    3239    else:
    33         tz = ''
     40        tz = 0
    3441    dates = d.split('-')
    3542    times = t.split(':')
    3643    seconds = times[2]
     
    3946    else:
    4047        microseconds = '0'
    4148    return datetime.datetime(int(dates[0]), int(dates[1]), int(dates[2]),
    42         int(times[0]), int(times[1]), int(seconds), int(float('.'+microseconds) * 1000000))
     49        int(times[0]), int(times[1]), int(seconds),
     50        int(float('.'+microseconds) * 1000000),
     51        tzinfo=FixedOffset(tz))
    4352
    4453def typecast_boolean(s):
    4554    if s is None: return None
  • django/utils/timesince.py

     
    11import time, math, datetime
     2from tzinfo import LocalTimezone
    23
    34def timesince(d, now=None):
    45    """
     
    67    as a nicely formatted string, e.g "10 minutes"
    78    Adapted from http://blog.natbat.co.uk/archive/2003/Jun/14/time_since
    89    """
    9     original = time.mktime(d.timetuple())
    1010    chunks = (
    1111      (60 * 60 * 24 * 365, 'year'),
    1212      (60 * 60 * 24 * 30, 'month'),
     
    1414      (60 * 60, 'hour'),
    1515      (60, 'minute')
    1616    )
    17     if not now:
    18         now = time.time()
    19     since = now - original
     17    if now:
     18        t = time.mktime(now)
     19    else:
     20        t = time.localtime()
     21    if d.tzinfo:
     22        tz = LocalTimezone()
     23    else:
     24        tz = None
     25    now = datetime.datetime(t[0], t[1], t[2], t[3], t[4], t[5], tzinfo=tz)
     26    delta = now - d
     27    since = delta.days * 24 * 60 * 60 + delta.seconds
    2028    # Crazy iteration syntax because we need i to be current index
    2129    for i, (seconds, name) in zip(range(len(chunks)), chunks):
    2230        count = math.floor(since / seconds)
Back to Top