[Python-checkins] python/nondist/sandbox/datetime datetime.py,1.108,1.109 doc.txt,1.55,1.56 test_datetime.py,1.69,1.70
tim_one@users.sourceforge.net
tim_one@users.sourceforge.net
Sun, 15 Dec 2002 16:25:36 -0800
- Previous message: [Python-checkins] python/nondist/sandbox/datetime test_datetime.py,1.68,1.69 test_both.py,1.89,NONE
- Next message: [Python-checkins] python/nondist/sandbox/datetime datetime.c,1.75,1.76 obj_date.c,1.55,1.56 obj_time.c,1.18,1.19
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
Update of /cvsroot/python/python/nondist/sandbox/datetime
In directory sc8-pr-cvs1:/tmp/cvs-serv7451
Modified Files:
datetime.py doc.txt test_datetime.py
Log Message:
Documented "correct" strftime behavior for %z and %Z. Implemented
correct behavior in the Python implementation. Added some tests. Noted
that the C implementation remains broken in this respect (even for a
naive object, on Windows at home %z and %Z both get replaced by "Eastern
Standard Time"; before this checkin, that was also true under the Python
implementation).
Index: datetime.py
===================================================================
RCS file: /cvsroot/python/python/nondist/sandbox/datetime/datetime.py,v
retrieving revision 1.108
retrieving revision 1.109
diff -C2 -d -r1.108 -r1.109
*** datetime.py 15 Dec 2002 18:30:49 -0000 1.108
--- datetime.py 16 Dec 2002 00:25:34 -0000 1.109
***************
*** 164,170 ****
# 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:
--- 164,175 ----
# Correctly substitute for %z and %Z escapes in strftime formats.
! def _wrap_strftime(object, format, timetuple):
! # Don't call utcoffset() or tzname() unless actually needed.
! zreplace = None # the string to use for %z
! Zreplace = None # the string to use for %Z
!
! # Scan format for %z and %Z escapes, replacing as needed.
! newformat = []
! push = newformat.append
i, n = 0, len(format)
while i < n:
***************
*** 176,186 ****
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('%')
--- 181,206 ----
i += 1
if ch == 'z':
! if zreplace is None:
! zreplace = ""
! if hasattr(object, "utcoffset"):
! offset = object.utcoffset()
! if offset is not None:
! sign = '+'
! if offset < 0:
! offset = -offset
! sign = '-'
! h, m = divmod(offset, 60)
! zreplace = '%c%02d%02d' % (sign, h, m)
! assert '%' not in zreplace
! newformat.append(zreplace)
elif ch == 'Z':
! if Zreplace is None:
! Zreplace = ""
! if hasattr(object, "tzname"):
! s = object.tzname()
! if s is not None:
! # strftime is going to have at this: escape %
! Zreplace = s.replace('%', '%%')
! newformat.append(Zreplace)
else:
push('%')
***************
*** 190,194 ****
else:
push(ch)
! return "".join(result)
def _check_utc_offset(name, offset):
--- 210,215 ----
else:
push(ch)
! newformat = "".join(newformat)
! return _time.strftime(newformat, timetuple)
def _check_utc_offset(name, offset):
***************
*** 623,627 ****
def strftime(self, fmt):
"Format using strftime()."
! return _time.strftime(fmt, self.timetuple())
def isoformat(self):
--- 644,648 ----
def strftime(self, fmt):
"Format using strftime()."
! return _wrap_strftime(self, fmt, self.timetuple())
def isoformat(self):
***************
*** 853,859 ****
to underlying strftime should not be used.
"""
! return _time.strftime(fmt, (0, 0, 0, self.__hour, self.__minute,
! self.__second, 0, 0, -1))
!
def __nonzero__(self):
--- 874,881 ----
to underlying strftime should not be used.
"""
! timetuple = (0, 0, 0,
! self.__hour, self.__minute, self.__second,
! 0, 0, -1)
! return _wrap_strftime(self, fmt, timetuple)
def __nonzero__(self):
***************
*** 1025,1048 ****
__str__ = isoformat
-
- def strftime(self, fmt):
- """Format using strftime(). The date part of the timestamp passed
- to underlying strftime should not be used.
-
- You can use %Z to refer to the timezone name and %z to refer to its
- 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)
# Timezone functions
--- 1047,1050 ----
Index: doc.txt
===================================================================
RCS file: /cvsroot/python/python/nondist/sandbox/datetime/doc.txt,v
retrieving revision 1.55
retrieving revision 1.56
diff -C2 -d -r1.55 -r1.56
*** doc.txt 15 Dec 2002 18:30:49 -0000 1.55
--- doc.txt 16 Dec 2002 00:25:34 -0000 1.56
***************
*** 4,8 ****
- The custom %z and %Z format codes for timetz and datetimetz
! .strftime needs a C implementation (yuck).
- LaTeXize the docs.
--- 4,9 ----
- The custom %z and %Z format codes for timetz and datetimetz
! .strftime needs a C implementation (yuck). More generally,
! %z and %Z are plain busted in the C implementation.
- LaTeXize the docs.
***************
*** 161,164 ****
--- 162,197 ----
+ strftime() Behavior
+ ===================
+ date, datetime, datetimetz, time, and timetz objects all support
+ a strftime(format) method, to create a string representing the time
+ under the control of an explicit format string. Broadly speaking,
+ d.strftime(fmt)
+ acts like the time module's
+ time.strftime(fmt, d.timetuple())
+ although not all objects support a timetuple() method.
+
+ For time and timetz objects, format codes for year, month, and day
+ should not be used, as time objects have no such values. 0 is used
+ instead.
+
+ For date objects, format codes for hours, minutes, and seconds should
+ not be used, as date objects have no such values. 0 is used insted.
+
+ For a naive object, the %z and %Z format codes are replaced by
+ empty strings.
+
+ For an aware object:
+
+ - %z: self.utcoffset() is transformed into a 5-character
+ string of the form +HHMM or -HHMM, where HH is a 2-digit string
+ giving the number of UTC offset hours, and MM is a 2-digit string
+ giving the number of UTC offset minutes. For example, if
+ utcoffset() returns -180, %z is replaced with string "-0300".
+
+ - %Z: If self.tzname() returns None, %Z is replaced by an empty string.
+ Else %Z is replaced by the returned value, which must be a string.
+
+
class timedelta
===============
***************
*** 442,447 ****
Return a string representing the date, controlled by an explicit
format string. Format codes referring to hours, minutes or seconds
! will see 0 values. d.strftime(f) is the same as
! time.strftime(f, d.timetuple()).
--- 475,479 ----
Return a string representing the date, controlled by an explicit
format string. Format codes referring to hours, minutes or seconds
! will see 0 values. See the section on strftime() behavior.
***************
*** 632,637 ****
- strftime(format)
Return a string representing the date and time, controlled by an
! explicit format string. d.strftime(f) is the same as
! time.strftime(f, d.timetuple()).
--- 664,668 ----
- strftime(format)
Return a string representing the date and time, controlled by an
! explicit format string. See the section on strftime() behavior.
***************
*** 704,710 ****
- strftime(format)
Return a string representing the time, controlled by an explicit
! format string. Format codes for any fields other than hour, minute
! and second should not be used, since a time object has meaningful
! values only for those fields.
--- 735,739 ----
- strftime(format)
Return a string representing the time, controlled by an explicit
! format string. See the section on strftime() behavior.
***************
*** 900,916 ****
- strftime(format)
Return a string representing the time, controlled by an explicit
! format string. Format codes for any fields other than hour, minute,
! second and time zone should not be used, since a timetz object has
! meaningful values only for those fields.
! Format code %Z: If self.tzname() returns None, %Z is replaced by
! an empty string. Else %Z is replaced by the returned value, which
! must be a string.
! Format code %z: This is an extension to the usual set of format
! codes. If self.uctoffset() returns None, %z is replaced by an empty
! string. Else the return value is transformed into a 5-character
! string of the form +HHMM or -HHMM, and replaces %z, where HH is a
! 2-digit string giving the number of UTC offset hours, and MM is a
! 2-digit string giving the number of UTC offset minutes.
! XXX Sheesh. This needs an example.
- utcoffset()
--- 929,933 ----
- strftime(format)
Return a string representing the time, controlled by an explicit
! format string. See the section on strftime() behavior.
- utcoffset()
***************
*** 1054,1057 ****
--- 1071,1075 ----
ctime()
__str__()
+ strftime(format)
These are the same as the datetime methods of the same names.
***************
*** 1111,1119 ****
str(d) is equivalent to d.isoformat(' ').
-
- - strftime(format)
- Return a string representing the date and time, controlled by an
- explicit format string. See timetz.strftime() for the treatment
- of the %Z and %z format codes.
--- 1129,1132 ----
Index: test_datetime.py
===================================================================
RCS file: /cvsroot/python/python/nondist/sandbox/datetime/test_datetime.py,v
retrieving revision 1.69
retrieving revision 1.70
diff -C2 -d -r1.69 -r1.70
*** test_datetime.py 15 Dec 2002 23:36:36 -0000 1.69
--- test_datetime.py 16 Dec 2002 00:25:34 -0000 1.70
***************
*** 13,16 ****
--- 13,18 ----
import unittest
+ # XXX strftime is broken in the C implementation, when using %z or %Z.
+
# Import the right implementation, under name "datetime".
TESTING_C = 'c' in sys.argv
***************
*** 770,773 ****
--- 772,778 ----
self.assertRaises(TypeError, t.strftime, 42) # arg wrong type
+ # A naive object replaces %z and %Z w/ empty strings.
+ self.assertEqual(t.strftime("'%z' '%Z'"), "'' ''")
+
def test_resolution_info(self):
self.assert_(isinstance(self.theclass.min, self.theclass))
***************
*** 1415,1418 ****
--- 1420,1425 ----
t = self.theclass(1, 2, 3, 4)
self.assertEqual(t.strftime('%H %M %S'), "01 02 03")
+ # A naive object replaces %z and %Z with empty strings.
+ self.assertEqual(t.strftime("'%z' '%Z'"), "'' ''")
def test_str(self):
***************
*** 1565,1571 ****
self.assertEqual(repr(t5), d + "timetz(0, 0, 0, 40, tzinfo=utc)")
- # XXX %z and %Z don't work correctly in C yet.
- if TESTING_C:
- return
self.assertEqual(t1.strftime("%H:%M:%S %%Z=%Z %%z=%z"),
"07:47:00 %Z=EST %z=-0500")
--- 1572,1575 ----
- Previous message: [Python-checkins] python/nondist/sandbox/datetime test_datetime.py,1.68,1.69 test_both.py,1.89,NONE
- Next message: [Python-checkins] python/nondist/sandbox/datetime datetime.c,1.75,1.76 obj_date.c,1.55,1.56 obj_time.c,1.18,1.19
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]