[Python-checkins] python/dist/src/Doc/lib libdatetime.tex,1.34,1.35 tzinfo-examples.py,1.5,1.6

tim_one@users.sourceforge.net tim_one@users.sourceforge.net
Mon, 20 Jan 2003 14:54:40 -0800


Update of /cvsroot/python/python/dist/src/Doc/lib
In directory sc8-pr-cvs1:/tmp/cvs-serv20501/python/Doc/lib

Modified Files:
	libdatetime.tex tzinfo-examples.py 
Log Message:
New rule for tzinfo subclasses handling both standard and daylight time:
When daylight time ends, an hour repeats on the local clock (for example,
in US Eastern, the clock jumps from 1:59 back to 1:00 again).  Times in
the repeated hour are ambiguous.  A tzinfo subclass that wants to play
with astimezone() needs to treat times in the repeated hour as being
standard time.  astimezone() previously required that such times be
treated as daylight time.  There seems no killer argument either way,
but Guido wants the standard-time version, and it does seem easier the
new way to code both American (local-time based) and European (UTC-based)
switch rules, and the astimezone() implementation is simpler.


Index: libdatetime.tex
===================================================================
RCS file: /cvsroot/python/python/dist/src/Doc/lib/libdatetime.tex,v
retrieving revision 1.34
retrieving revision 1.35
diff -C2 -d -r1.34 -r1.35
*** libdatetime.tex	9 Jan 2003 13:46:30 -0000	1.34
--- libdatetime.tex	20 Jan 2003 22:54:38 -0000	1.35
***************
*** 31,35 ****
  For applications requiring more, \class{datetime} and \class{time}
  objects have an optional time zone information member,
! \member{tzinfo}, that can contain an instance of a subclass of 
  the abstract \class{tzinfo} class.  These \class{tzinfo} objects
  capture information about the offset from UTC time, the time zone
--- 31,35 ----
  For applications requiring more, \class{datetime} and \class{time}
  objects have an optional time zone information member,
! \member{tzinfo}, that can contain an instance of a subclass of
  the abstract \class{tzinfo} class.  These \class{tzinfo} objects
  capture information about the offset from UTC time, the time zone
***************
*** 1049,1054 ****
      If \method{utcoffset()} does not return \code{None},
      \method{dst()} should not return \code{None} either.
- \end{methoddesc}
  
  
  \begin{methoddesc}{dst}{self, dt}
--- 1049,1056 ----
      If \method{utcoffset()} does not return \code{None},
      \method{dst()} should not return \code{None} either.
  
+     The default implementation of \method{utcoffset()} raises
+     \exception{NotImplementedError}.
+ \end{methoddesc}
  
  \begin{methoddesc}{dst}{self, dt}
***************
*** 1061,1065 ****
    already been added to the UTC offset returned by
    \method{utcoffset()}, so there's no need to consult \method{dst()}
!   unless you're interested in displaying DST info separately.  For
    example, \method{datetime.timetuple()} calls its \member{tzinfo}
    member's \method{dst()} method to determine how the
--- 1063,1067 ----
    already been added to the UTC offset returned by
    \method{utcoffset()}, so there's no need to consult \method{dst()}
!   unless you're interested in obtaining DST info separately.  For
    example, \method{datetime.timetuple()} calls its \member{tzinfo}
    member's \method{dst()} method to determine how the
***************
*** 1081,1084 ****
--- 1083,1090 ----
    ensure it.
  
+   The default implementation of \method{dst()} raises
+   \exception{NotImplementedError}.
+ \end{methoddesc}
+ 
  \begin{methoddesc}{tzname}{self, dt}
    Return the timezone name corresponding to the \class{datetime}
***************
*** 1093,1098 ****
    of \var{dt} passed, especially if the \class{tzinfo} class is
    accounting for daylight time.
- \end{methoddesc}
  
  \end{methoddesc}
  
--- 1099,1105 ----
    of \var{dt} passed, especially if the \class{tzinfo} class is
    accounting for daylight time.
  
+   The default implementation of \method{tzname()} raises
+   \exception{NotImplementedError}.
  \end{methoddesc}
  
***************
*** 1107,1112 ****
  best response.  For example, returning \code{None} is appropriate if the
  class wishes to say that time objects don't participate in the
! \class{tzinfo} protocol.  In other applications, it may be more useful
! for \code{utcoffset(None)} to return the standard UTC offset.
  
  When a \class{datetime} object is passed in response to a
--- 1114,1120 ----
  best response.  For example, returning \code{None} is appropriate if the
  class wishes to say that time objects don't participate in the
! \class{tzinfo} protocol.  It may be more useful for \code{utcoffset(None)}
! to return the standard UTC offset, as there is no other convention for
! discovering the standard offset.
  
  When a \class{datetime} object is passed in response to a
***************
*** 1115,1119 ****
  user code calls \class{tzinfo} methods directly.  The intent is that
  the \class{tzinfo} methods interpret \var{dt} as being in local time,
! and not need to worry about objects in other timezones.
  
  Example \class{tzinfo} classes:
--- 1123,1127 ----
  user code calls \class{tzinfo} methods directly.  The intent is that
  the \class{tzinfo} methods interpret \var{dt} as being in local time,
! and not need worry about objects in other timezones.
  
  Example \class{tzinfo} classes:
***************
*** 1121,1125 ****
  \verbatiminput{tzinfo-examples.py}
  
! Note that there are unavoidable subtleties twice per year in a tzinfo
  subclass accounting for both standard and daylight time, at the DST
  transition points.  For concreteness, consider US Eastern (UTC -0500),
--- 1129,1134 ----
  \verbatiminput{tzinfo-examples.py}
  
! Note that there are unavoidable subtleties twice per year in a
! \class{tzinfo}
  subclass accounting for both standard and daylight time, at the DST
  transition points.  For concreteness, consider US Eastern (UTC -0500),
***************
*** 1141,1170 ****
  day, so \code{astimezone(Eastern)} won't deliver a result with
  \code{hour==2} on the
! day DST begins.  How an Eastern instance chooses to interpret 2:MM on
! that day is its business.  The example Eastern implementation above
! chose to
! consider it as a time in EDT, simply because it "looks like it's
! after 2:00", and so synonymous with the EST 1:MM times on that day.
! Your Eastern class may wish, for example, to raise an exception instead
! when it sees a 2:MM time on the day EDT begins.
  
  When DST ends (the "end" line), there's a potentially worse problem:
! there's an hour that can't be spelled unambiguously in local wall time, the
! hour beginning at the moment DST ends.  In this example, that's times of
! the form 6:MM UTC on the day daylight time ends.  The local wall clock
  leaps from 1:59 (daylight time) back to 1:00 (standard time) again.
! 1:MM is taken as daylight time (it's "before 2:00"), so maps to 5:MM UTC.
! 2:MM is taken as standard time (it's "after 2:00"), so maps to 7:MM UTC.
! There is no local time that maps to 6:MM UTC on this day.
  
! Just as the wall clock does, \code{astimezone(Eastern)} maps both UTC
! hours 5:MM
! and 6:MM to Eastern hour 1:MM on this day.  However, this result is
! ambiguous (there's no way for Eastern to know which repetition of 1:MM
! is intended).  Applications that can't bear such ambiguity
! should avoid using hybrid tzinfo classes; there are no
! ambiguities when using UTC, or any other fixed-offset tzinfo subclass
! (such as a class representing only EST (fixed offset -5 hours), or only
! EDT (fixed offset -4 hours)).
  
  
--- 1150,1176 ----
  day, so \code{astimezone(Eastern)} won't deliver a result with
  \code{hour==2} on the
! day DST begins.  In order for \method{astimezone()} to make this
! guarantee, the \class{tzinfo} \method{dst()} method must consider times
! in the "missing hour" (2:MM for Eastern) to be in daylight time.
  
  When DST ends (the "end" line), there's a potentially worse problem:
! there's an hour that can't be spelled unambiguously in local wall time:
! the last hour of daylight time.  In Eastern, that's times of
! the form 5:MM UTC on the day daylight time ends.  The local wall clock
  leaps from 1:59 (daylight time) back to 1:00 (standard time) again.
! Local times of the form 1:MM are ambiguous.  \method{astimezone()} mimics
! the local clock's behavior by mapping two adjacent UTC hours into the
! same local hour then.  In the Eastern example, UTC times of the form
! 5:MM and 6:MM both map to 1:MM when converted to Eastern.  In order for
! \method{astimezone()} to make this guarantee, the \class{tzinfo}
! \method{dst()} method must consider times in the "repeated hour" to be in
! standard time.  This is easily arranged, as in the example, by expressing
! DST switch times in the time zone's standard local time.
  
! Applications that can't bear such ambiguities should avoid using hybrid
! \class{tzinfo} subclasses; there are no ambiguities when using UTC, or
! any other fixed-offset \class{tzinfo} subclass (such as a class
! representing only EST (fixed offset -5 hours), or only EDT (fixed offset
! -4 hours)).
  
  

Index: tzinfo-examples.py
===================================================================
RCS file: /cvsroot/python/python/dist/src/Doc/lib/tzinfo-examples.py,v
retrieving revision 1.5
retrieving revision 1.6
diff -C2 -d -r1.5 -r1.6
*** tzinfo-examples.py	9 Jan 2003 19:52:17 -0000	1.5
--- tzinfo-examples.py	20 Jan 2003 22:54:38 -0000	1.6
***************
*** 92,96 ****
  # and ends at 2am (DST time; 1am standard time) on the last Sunday of Oct.
  # which is the first Sunday on or after Oct 25.
! DSTEND = datetime(1, 10, 25, 2)
  
  class USTimeZone(tzinfo):
--- 92,96 ----
  # and ends at 2am (DST time; 1am standard time) on the last Sunday of Oct.
  # which is the first Sunday on or after Oct 25.
! DSTEND = datetime(1, 10, 25, 1)
  
  class USTimeZone(tzinfo):