[Python-checkins] python/nondist/sandbox/datetime datetime.py,1.95,1.96 test_datetime.py,1.65,1.66
tim_one@users.sourceforge.net
tim_one@users.sourceforge.net
Wed, 11 Dec 2002 20:03:49 -0800
Update of /cvsroot/python/python/nondist/sandbox/datetime
In directory sc8-pr-cvs1:/tmp/cvs-serv23554
Modified Files:
datetime.py test_datetime.py
Log Message:
Implement tzinfo.strftime() correctly. This includes:
- Don't call utcoffset or tzname unless they're actually needed by
the format string.
- Handle % escapes in the format string correctly. For example,
%%Z is the string %Z, not a % followed by a reference to the
format code %Z.
- If %Z is used and the tzname has any % characters, escape them.
All this was a minor PITA in Python, and will be a major PITA when
rewritten in C.
Index: datetime.py
===================================================================
RCS file: /cvsroot/python/python/nondist/sandbox/datetime/datetime.py,v
retrieving revision 1.95
retrieving revision 1.96
diff -C2 -d -r1.95 -r1.96
*** datetime.py 12 Dec 2002 03:24:55 -0000 1.95
--- datetime.py 12 Dec 2002 04:03:47 -0000 1.96
***************
*** 161,164 ****
--- 161,193 ----
return result
+ # Correctly substitute for %z and %Z escapes in strftime formats.
+ def _handle_z_escapes(format, Zreplace, zreplace):
+ result = []
+ push = result.append
+ i, n = 0, len(format)
+ while i < n:
+ ch = format[i]
+ i += 1
+ if ch == '%':
+ if i < n:
+ ch = format[i]
+ i += 1
+ if ch == 'z':
+ s = zreplace()
+ assert '%' not in s
+ result.append(s)
+ elif ch == 'Z':
+ # strftime is going to have at this, so escape %
+ s = Zreplace().replace('%', '%%')
+ result.append(s)
+ else:
+ push('%')
+ push(ch)
+ else:
+ push('%')
+ else:
+ push(ch)
+ return "".join(result)
+
# This is a start at a struct tm workalike. Goals:
#
***************
*** 961,976 ****
def _tzstr(self, sep=":"):
"""Return formatted timezone offset (+xx:xx) or None."""
! if self.__tzinfo is not None:
! off = self.__tzinfo.utcoffset(self)
! if off is not None:
! if off < 0:
! sign = "-"
! off = -off
! else:
! sign = "+"
! hh, mm = divmod(off, 60)
! if hh >= 24:
! raise ValueError("utcoffset must be in -1439 .. 1439")
! return "%s%02d%s%02d" % (sign, hh, sep, mm)
def __repr__(self):
--- 990,1005 ----
def _tzstr(self, sep=":"):
"""Return formatted timezone offset (+xx:xx) or None."""
! off = self.utcoffset()
! if off is not None:
! if off < 0:
! sign = "-"
! off = -off
! else:
! sign = "+"
! hh, mm = divmod(off, 60)
! if hh >= 24:
! raise ValueError("utcoffset must be in -1439 .. 1439")
! off = "%s%02d%s%02d" % (sign, hh, sep, mm)
! return off
def __repr__(self):
***************
*** 1002,1010 ****
UTC offset (+zzzz).
"""
! tz = self._tzstr(sep="")
! if tz:
! fmt = fmt.replace("%z", tz).replace("%Z", self.tzinfo.tzname(None))
! else:
! fmt = fmt.replace("%z", "").replace("%Z", "")
return super(timetz, self).strftime(fmt)
--- 1031,1045 ----
UTC offset (+zzzz).
"""
!
! # Don't call utcoffset or tzname unless the format string really
! # needs them -- there's no requirement in the docs that a tzinfo
! # object implement every method.
! def getz():
! return self._tzstr('') or ""
!
! def getZ():
! return self.tzname() or ""
!
! fmt = _handle_z_escapes(fmt, getZ, getz)
return super(timetz, self).strftime(fmt)
Index: test_datetime.py
===================================================================
RCS file: /cvsroot/python/python/nondist/sandbox/datetime/test_datetime.py,v
retrieving revision 1.65
retrieving revision 1.66
diff -C2 -d -r1.65 -r1.66
*** test_datetime.py 12 Dec 2002 02:55:16 -0000 1.65
--- test_datetime.py 12 Dec 2002 04:03:47 -0000 1.66
***************
*** 42,49 ****
t3 = timetz(13, 47, tzinfo=met)
# XXX Most of the tests here have moved into test_both.py.
! self.assertEqual(t1.strftime("%H:%M:%S %Z %z"), "07:47:00 EST -0500")
self.assertEqual(t2.strftime("%H:%M:%S %Z %z"), "12:47:00 UTC +0000")
self.assertEqual(t3.strftime("%H:%M:%S %Z %z"), "13:47:00 MET +0100")
class TestDateTime(unittest.TestCase):
--- 42,54 ----
t3 = timetz(13, 47, tzinfo=met)
# XXX Most of the tests here have moved into test_both.py.
! self.assertEqual(t1.strftime("%H:%M:%S %%Z=%Z %%z=%z"),
! "07:47:00 %Z=EST %z=-0500")
self.assertEqual(t2.strftime("%H:%M:%S %Z %z"), "12:47:00 UTC +0000")
self.assertEqual(t3.strftime("%H:%M:%S %Z %z"), "13:47:00 MET +0100")
+ yuck = FixedOffset(-1439, "%z %Z %%z%%Z")
+ t1 = timetz(23, 59, tzinfo=yuck)
+ self.assertEqual(t1.strftime("%H:%M %%Z='%Z' %%z='%z'"),
+ "23:59 %Z='%z %Z %%z%%Z' %z='-2359'")
class TestDateTime(unittest.TestCase):