Index: django/utils/tzinfo.py
===================================================================
--- django/utils/tzinfo.py	(revision 0)
+++ django/utils/tzinfo.py	(revision 0)
@@ -0,0 +1,52 @@
+"""Implementation of a tzinfo-classes for use with datetime.datetime."""
+
+import time
+from datetime import timedelta, tzinfo
+
+ZERO = timedelta(0)
+STDOFFSET = timedelta(seconds=-time.timezone)
+DSTOFFSET = timedelta(seconds=-time.altzone)
+DSTDIFF = DSTOFFSET - STDOFFSET
+
+class FixedOffset(tzinfo):
+    """Fixed offset in minutes east from UTC."""
+
+    def __init__(self, offset):
+        self.__offset = timedelta(minutes=offset)
+        # FIXME -- Not really a name...
+        self.__name = "%+03d%02d" % (offset / 60, offset % 60)
+
+    def utcoffset(self, dt):
+        return self.__offset
+
+    def tzname(self, dt):
+        return self.__name
+
+    def dst(self, dt):
+        return ZERO
+
+class LocalTimezone(tzinfo):
+    """Proxy timezone information from time module."""
+
+    def utcoffset(self, dt):
+        if self._isdst(dt):
+            return DSTOFFSET
+        else:
+            return STDOFFSET
+
+    def dst(self, dt):
+        if self._isdst(dt):
+            return DSTDIFF
+        else:
+            return ZERO
+
+    def tzname(self, dt):
+        return time.tzname[self._isdst(dt)]
+
+    def _isdst(self, dt):
+        tt = (dt.year, dt.month, dt.day,
+              dt.hour, dt.minute, dt.second,
+              dt.weekday(), 0, -1)
+        stamp = time.mktime(tt)
+        tt = time.localtime(stamp)
+        return tt.tm_isdst > 0
Index: django/utils/dateformat.py
===================================================================
--- django/utils/dateformat.py	(revision 632)
+++ django/utils/dateformat.py	(working copy)
@@ -11,8 +11,14 @@
 >>>
 """
 
+# FIXME -- Try this in a template and weep
+#   { now:"\T\h\i\s \i\s \e\s\c\a\p\e\d" }
+# or
+#   { now:"\\T\\h\\i\\s \\i\\s \\e\\s\\c\\a\\p\\e\\d" }
+
 from calendar import isleap
 from dates import MONTHS, MONTHS_AP, WEEKDAYS
+from tzinfo import LocalTimezone
 
 class DateFormat:
     year_days = [None, 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334]
@@ -20,6 +26,10 @@
     def __init__(self, d):
         self.date = d
 
+        self.timezone = getattr(self.date, 'tzinfo', None)
+        if not self.timezone:
+            self.timezone = LocalTimezone(self.date)
+
     def a(self):
         "'a.m.' or 'p.m.'"
         if self.date.hour > 11:
@@ -84,7 +94,7 @@
 
     def I(self):
         "'1' if Daylight Savings Time, '0' otherwise."
-        raise NotImplementedError
+        return self.timezone.dst()
 
     def j(self):
         "Day of the month without leading zeros; i.e. '1' to '31'"
@@ -116,7 +126,8 @@
 
     def O(self):
         "Difference to Greenwich time in hours; e.g. '+0200'"
-        raise NotImplementedError
+        tz = self.timezone.utcoffset(self.date)
+        return "%+03d%02d" % (tz.seconds / 3600, (tz.seconds / 60) % 60)
 
     def P(self):
         """
@@ -158,7 +169,7 @@
 
     def T(self):
         "Time zone of this machine; e.g. 'EST' or 'MDT'"
-        raise NotImplementedError
+        return self.timezone.tzname(self.date)
 
     def U(self):
         "Seconds since the Unix epoch (January 1 1970 00:00:00 GMT)"
@@ -216,14 +227,14 @@
         """Time zone offset in seconds (i.e. '-43200' to '43200'). The offset
         for timezones west of UTC is always negative, and for those east of UTC
         is always positive."""
-        raise NotImplementedError
+        return self.timezone.utcoffset(self.date).seconds
 
     def format(self, formatstr):
         result = ''
         for char in formatstr:
-            try:
+            if hasattr(self, char):
                 result += str(getattr(self, char)())
-            except AttributeError:
+            else:
                 result += char
         return result
 
Index: django/core/db/typecasts.py
===================================================================
--- django/core/db/typecasts.py	(revision 632)
+++ django/core/db/typecasts.py	(working copy)
@@ -1,4 +1,5 @@
 import datetime
+from django.utils.tzinfo import FixedOffset
 
 ###############################################
 # Converters from database (string) to Python #
@@ -25,12 +26,12 @@
     # it away, but in the future we may make use of it.
     if '-' in t:
         t, tz = t.split('-', 1)
-        tz = '-' + tz
+        tz = - int(tz) * 60
     elif '+' in t:
         t, tz = t.split('+', 1)
-        tz = '+' + tz
+        tz = int(tz) * 60
     else:
-        tz = ''
+        tz = 0
     dates = d.split('-')
     times = t.split(':')
     seconds = times[2]
@@ -39,7 +40,9 @@
     else:
         microseconds = '0'
     return datetime.datetime(int(dates[0]), int(dates[1]), int(dates[2]),
-        int(times[0]), int(times[1]), int(seconds), int(float('.'+microseconds) * 1000000))
+        int(times[0]), int(times[1]), int(seconds),
+        int(float('.'+microseconds) * 1000000),
+        tzinfo=FixedOffset(tz))
 
 def typecast_boolean(s):
     if s is None: return None
Index: django/utils/timesince.py
===================================================================
--- django/utils/timesince.py	(revision 632)
+++ django/utils/timesince.py	(working copy)
@@ -1,4 +1,5 @@
 import time, math, datetime
+from tzinfo import LocalTimezone
 
 def timesince(d, now=None):
     """
@@ -6,7 +7,6 @@
     as a nicely formatted string, e.g "10 minutes"
     Adapted from http://blog.natbat.co.uk/archive/2003/Jun/14/time_since
     """
-    original = time.mktime(d.timetuple())
     chunks = (
       (60 * 60 * 24 * 365, 'year'),
       (60 * 60 * 24 * 30, 'month'),
@@ -14,9 +14,17 @@
       (60 * 60, 'hour'),
       (60, 'minute')
     )
-    if not now:
-        now = time.time()
-    since = now - original
+    if now:
+        t = time.mktime(now)
+    else:
+        t = time.localtime()
+    if d.tzinfo:
+        tz = LocalTimezone()
+    else:
+        tz = None
+    now = datetime.datetime(t[0], t[1], t[2], t[3], t[4], t[5], tzinfo=tz)
+    delta = now - d
+    since = delta.days * 24 * 60 * 60 + delta.seconds
     # Crazy iteration syntax because we need i to be current index
     for i, (seconds, name) in zip(range(len(chunks)), chunks):
         count = math.floor(since / seconds)
