Ticket #479: dateformat.patch
File dateformat.patch, 13.7 KB (added by , 19 years ago) |
---|
-
django/utils/tzinfo.py
==== Patch <dateformat> level 1 Source: d410f328-f502-0410-afc1-bf1322476e67:/django/patches/djtime:2758 Target: d410f328-f502-0410-afc1-bf1322476e67:/django/trunk:2731 Log: r2748@moria: sune | 2005-10-13 08:38:55 +0200 Existing patches. r2754@moria: sune | 2005-10-13 10:37:00 +0200 Revert timezone-parsing in db typecasts. r2755@moria: sune | 2005-10-13 10:37:21 +0200 Add dateformat unittests. r2756@moria: sune | 2005-10-13 10:39:02 +0200 Grab timezone-name from __init__ argument. r2757@moria: sune | 2005-10-13 10:39:29 +0200 Implement / fix all but "Swatch internet time" formats. r2758@moria: sune | 2005-10-13 11:00:04 +0200 Fix dateformat to handle escaped chars. === django/utils/tzinfo.py ==================================================================
1 """Implementation of a tzinfo-classes for use with datetime.datetime.""" 2 3 import time 4 from datetime import timedelta, tzinfo 5 6 ZERO = timedelta(0) 7 STDOFFSET = timedelta(seconds=-time.timezone) 8 DSTOFFSET = timedelta(seconds=-time.altzone) 9 DSTDIFF = DSTOFFSET - STDOFFSET 10 11 class 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 __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 ZERO 30 31 class LocalTimezone(tzinfo): 32 """Proxy timezone information from time module.""" 33 def __init__(self, dt): 34 tzinfo.__init__(self, dt) 35 self._tzname = time.tzname[self._isdst(dt)] 36 def __repr__(self): 37 return self._tzname 38 39 def utcoffset(self, dt): 40 if self._isdst(dt): 41 return DSTOFFSET 42 else: 43 return STDOFFSET 44 def dst(self, dt): 45 if self._isdst(dt): 46 return DSTDIFF 47 else: 48 return ZERO 49 def tzname(self, dt): 50 return time.tzname[self._isdst(dt)] 51 def _isdst(self, dt): 52 tt = (dt.year, dt.month, dt.day, 53 dt.hour, dt.minute, dt.second, 54 dt.weekday(), 0, -1) 55 stamp = time.mktime(tt) 56 tt = time.localtime(stamp) 57 return tt.tm_isdst > 0 -
django/utils/timesince.py
=== django/utils/timesince.py ==================================================================
1 1 import time, math, datetime 2 from tzinfo import LocalTimezone 2 3 3 4 def timesince(d, now=None): 4 5 """ … … 6 7 as a nicely formatted string, e.g "10 minutes" 7 8 Adapted from http://blog.natbat.co.uk/archive/2003/Jun/14/time_since 8 9 """ 9 original = time.mktime(d.timetuple())10 10 chunks = ( 11 11 (60 * 60 * 24 * 365, 'year'), 12 12 (60 * 60 * 24 * 30, 'month'), … … 14 14 (60 * 60, 'hour'), 15 15 (60, 'minute') 16 16 ) 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 20 28 # Crazy iteration syntax because we need i to be current index 21 29 for i, (seconds, name) in zip(range(len(chunks)), chunks): 22 30 count = math.floor(since / seconds) -
django/utils/dateformat.py
=== django/utils/dateformat.py ==================================================================
13 13 14 14 from calendar import isleap 15 15 from dates import MONTHS, MONTHS_AP, WEEKDAYS 16 from tzinfo import LocalTimezone 17 import time 18 import re 16 19 20 re_formatchars = re.compile(r'(?<!\\)([aABdDfFgGhHiIjlLmMnNOPrsStTUwWyYzZ])') 21 split_formatstr = re_formatchars.split 22 re_escaped = re.compile(r'\\(.)') 23 17 24 class DateFormat: 18 25 year_days = [None, 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334] 19 26 20 27 def __init__(self, d): 21 28 self.date = d 22 29 30 self.timezone = getattr(self.date, 'tzinfo', None) 31 if not self.timezone: 32 self.timezone = LocalTimezone(self.date) 33 23 34 def a(self): 24 35 "'a.m.' or 'p.m.'" 25 36 if self.date.hour > 11: … … 84 95 85 96 def I(self): 86 97 "'1' if Daylight Savings Time, '0' otherwise." 87 raise NotImplementedError 98 if self.timezone.dst(self.date): 99 return '1' 100 else: 101 return '0' 88 102 89 103 def j(self): 90 104 "Day of the month without leading zeros; i.e. '1' to '31'" … … 116 130 117 131 def O(self): 118 132 "Difference to Greenwich time in hours; e.g. '+0200'" 119 raise NotImplementedError 133 tz = self.timezone.utcoffset(self.date) 134 return "%+03d%02d" % (tz.seconds / 3600, (tz.seconds / 60) % 60) 120 135 121 136 def P(self): 122 137 """ … … 133 148 134 149 def r(self): 135 150 "RFC 822 formatted date; e.g. 'Thu, 21 Dec 2000 16:01:07 +0200'" 136 r aise NotImplementedError151 return self.format('D, j M Y H:i:s O') 137 152 138 153 def s(self): 139 154 "Seconds; i.e. '00' to '59'" … … 158 173 159 174 def T(self): 160 175 "Time zone of this machine; e.g. 'EST' or 'MDT'" 161 raise NotImplementedError 176 name = self.timezone.tzname(self.date) 177 if name is None: 178 name = self.format('O') 179 return name 162 180 163 181 def U(self): 164 182 "Seconds since the Unix epoch (January 1 1970 00:00:00 GMT)" 165 raise NotImplementedError 183 off = self.timezone.utcoffset(self.date) 184 return int(time.mktime(self.date.timetuple())) + off.seconds * 60 166 185 167 186 def w(self): 168 187 "Day of the week, numeric, i.e. '0' (Sunday) to '6' (Saturday)" 169 weekday = self.date.weekday() 170 if weekday == 0: 171 return 6 172 return weekday - 1 188 return (self.date.weekday() + 1) % 7 173 189 174 190 def W(self): 175 191 "ISO-8601 week number of year, weeks starting on Monday" … … 197 213 week_number -= 1 198 214 return week_number 199 215 216 def y(self): 217 "Year, 2 digits; e.g. '99'" 218 return str(self.date.year)[2:] 219 200 220 def Y(self): 201 221 "Year, 4 digits; e.g. '1999'" 202 222 return self.date.year 203 223 204 def y(self):205 "Year, 2 digits; e.g. '99'"206 return str(self.date.year)[2:]207 208 224 def z(self): 209 225 "Day of the year; i.e. '0' to '365'" 210 226 doy = self.year_days[self.date.month] + self.date.day … … 216 232 """Time zone offset in seconds (i.e. '-43200' to '43200'). The offset 217 233 for timezones west of UTC is always negative, and for those east of UTC 218 234 is always positive.""" 219 r aise NotImplementedError235 return self.timezone.utcoffset(self.date).seconds 220 236 221 237 def format(self, formatstr): 222 result = ''223 for char in formatstr:224 try:225 result += str(getattr(self, char)())226 e xcept AttributeError:227 result += char228 return result238 pieces = [] 239 for i, piece in enumerate(split_formatstr(formatstr)): 240 if i % 2: 241 pieces.append(str(getattr(self, piece)())) 242 elif piece: 243 pieces.append(re_escaped.sub(r'\1', piece)) 244 return ''.join(pieces) 229 245 230 246 class TimeFormat: 231 247 def __init__(self, t): -
tests/othertests/db_typecasts.py
=== tests/othertests/db_typecasts.py ==================================================================
1 1 # Unit tests for django.core.db.typecasts 2 2 3 3 from django.core.db import typecasts 4 from django.utils.tzinfo import FixedOffset 4 5 import datetime 5 6 6 7 TEST_CASES = { -
tests/othertests/dateformat.py
=== tests/othertests/dateformat.py ==================================================================
1 """ 2 >>> format(my_birthday, '') 3 '' 4 >>> format(my_birthday, 'a') 5 'p.m.' 6 >>> format(my_birthday, 'A') 7 'PM' 8 >>> format(my_birthday, 'j') 9 '7' 10 >>> format(my_birthday, 'l') 11 'Saturday' 12 >>> format(my_birthday, 'L') 13 'False' 14 >>> format(my_birthday, 'm') 15 '07' 16 >>> format(my_birthday, 'M') 17 'Jul' 18 >>> format(my_birthday, 'n') 19 '7' 20 >>> format(my_birthday, 'N') 21 'July' 22 >>> format(my_birthday, 'O') 23 '+0100' 24 >>> format(my_birthday, 'P') 25 '10 p.m.' 26 >>> format(my_birthday, 'r') 27 'Sat, 7 Jul 1979 22:00:00 +0100' 28 >>> format(my_birthday, 's') 29 '00' 30 >>> format(my_birthday, 'S') 31 'th' 32 >>> format(my_birthday, 't') 33 Traceback (most recent call last): 34 ... 35 NotImplementedError 36 >>> format(my_birthday, 'T') 37 'CET' 38 >>> format(my_birthday, 'U') 39 '300445200' 40 >>> format(my_birthday, 'w') 41 '6' 42 >>> format(my_birthday, 'W') 43 '27' 44 >>> format(my_birthday, 'y') 45 '79' 46 >>> format(my_birthday, 'Y') 47 '1979' 48 >>> format(my_birthday, 'z') 49 '188' 50 >>> format(my_birthday, 'Z') 51 '3600' 52 53 >>> format(summertime, 'I') 54 '1' 55 >>> format(summertime, 'O') 56 '+0200' 57 >>> format(wintertime, 'I') 58 '0' 59 >>> format(wintertime, 'O') 60 '+0100' 61 62 >>> format(my_birthday, 'Y z \\C\\E\\T') 63 '1979 188 CET' 64 """ 65 from django.utils.dateformat import format 66 import datetime 67 68 import os 69 import time 70 71 os.environ['TZ'] = 'Europe/Copenhagen' 72 time.tzset() 73 74 my_birthday = datetime.datetime(1979, 7, 7, 22, 00) 75 summertime = datetime.datetime(2005, 10, 30, 1, 00) 76 wintertime = datetime.datetime(2005, 10, 30, 4, 00)