@@ -734,32 +734,71 @@ \subsection{\class{datetime} Objects \label{datetime-datetime}}
734734
735735\begin {methoddesc }{astimezone}{tz}
736736 Return a \class {datetime} object with new \member {tzinfo} member
737- \var {tz}.
738- \var {tz} must be \code {None}, or an instance of a \class {tzinfo} subclass.
739- If \var {tz} is \code {None}, \var {self} is naive,
740- or \code {self.tzinfo}\ is \var {tz},
741- \code {self.astimezone(tz)} is equivalent to
742- \code {self.replace(tzinfo=tz)}: a new time zone object is attached
743- without any conversion of date or time members. Else \code {self.tzinfo}
744- and \var {tz} must implement the \method {utcoffset()} and \method {dst()}
745- \class {tzinfo} methods, and the date and time members are adjusted so
746- that the result is local time in time zone \var {tz}, representing the
747- same UTC time as \var {self}: after \code {astz = dt.astimezone(tz)},
748- \code {astz - astz.utcoffset()} will usually have the same date and time
749- members as \code {dt - dt.utcoffset()}. The discussion of class
750- \class {tzinfo} explains the cases at Daylight Saving Time
751- transition boundaries where this cannot be achieved (an issue only if
752- \var {tz} models both standard and daylight time).
737+ \var {tz}, adjusting the date and time members so the result is the
738+ same UTC time as \var {self}, but in \var {tz}'s local time.
739+
740+ \var {tz} must be an instance of a \class {tzinfo} subclass, and its
741+ \method {utcoffset()} and \method {dst()} methods must not return
742+ \code {None}. \var {self} must be aware (\code {\var {self}.tzinfo} must
743+ not be \code {None}, and \code {\var {self}.utcoffset()} must not return
744+ \code {None}).
745+
746+ If code{\var {self}.tzinfo} is \var {tz},
747+ \code {\var {self}.astimezone(\var {tz})} is equal to \var {self}: no
748+ adjustment of date or time members is performed.
749+ Else the result is local time in time zone \var {tz}, representing the
750+ same UTC time as \var {self}: after \code {\var {astz} =
751+ \var {dt}.astimezone(\var {tz})},
752+ \code {\var {astz} - \var {astz}.utcoffset()} will usually have the same
753+ date and time members as \code {\var {dt} - \var {dt}.utcoffset()}.
754+ The discussion of class \class {tzinfo} explains the cases at Daylight
755+ Saving Time transition boundaries where this cannot be achieved (an issue
756+ only if \var {tz} models both standard and daylight time).
757+
758+ If you merely want to attach a time zone object \var {tz} to a
759+ datetime \var {dt} without adjustment of date and time members,
760+ use \code {\var {dt}.replace(tzinfo=\var {tz})}. If
761+ you merely want to remove the time zone object from an aware datetime
762+ \var {dt} without conversion of date and time members, use
763+ \code {\var {dt}.replace(tzinfo=None)}.
764+
765+ Note that the default \method {tzinfo.fromutc()} method can be overridden
766+ in a \class {tzinfo} subclass to effect the result returned by
767+ \method {astimezone()}. Ignoring error cases, \method {astimezone()}
768+ acts like:
769+
770+ \begin {verbatim }
771+ def astimezone(self, tz):
772+ if self.tzinfo is tz:
773+ return self
774+ # Convert self to UTC, and attach the new time zone object.
775+ utc = (self - self.utcoffset()).replace(tzinfo=tz)
776+ # Convert from UTC to tz's local time.
777+ return tz.fromutc(utc)
778+ \end {verbatim }
753779\end {methoddesc }
754780
755781\begin {methoddesc }{utcoffset}{}
756782 If \member {tzinfo} is \code {None}, returns \code {None}, else
757- returns \code {tzinfo.utcoffset(self)}.
783+ returns \code {\var {self}.tzinfo.utcoffset(\var {self})}, and
784+ raises an exception if the latter doesn't return \code {None}, or
785+ a \class {timedelta} object representing a whole number of minutes
786+ with magnitude less than one day.
787+ \end {methoddesc }
788+
789+ \begin {methoddesc }{dst}{}
790+ If \member {tzinfo} is \code {None}, returns \code {None}, else
791+ returns \code {\var {self}.tzinfo.dst(\var {self})}, and
792+ raises an exception if the latter doesn't return \code {None}, or
793+ a \class {timedelta} object representing a whole number of minutes
794+ with magnitude less than one day.
758795\end {methoddesc }
759796
760797\begin {methoddesc }{tzname}{}
761798 If \member {tzinfo} is \code {None}, returns \code {None}, else
762- returns \code {tzinfo.tzname(self)}.
799+ returns \code {\var {self}.tzinfo.tzname(\var {self})},
800+ raises an exception if the latter doesn't return \code {None} or
801+ a string object,
763802\end {methoddesc }
764803
765804\begin {methoddesc }{timetuple}{}
@@ -989,17 +1028,25 @@ \subsection{\class{time} Objects \label{datetime-time}}
9891028
9901029\begin {methoddesc }{utcoffset}{}
9911030 If \member {tzinfo} is \code {None}, returns \code {None}, else
992- returns \code {tzinfo.utcoffset(self)}.
1031+ returns \code {\var {self}.tzinfo.utcoffset(None)}, and
1032+ raises an exception if the latter doesn't return \code {None} or
1033+ a \class {timedelta} object representing a whole number of minutes
1034+ with magnitude less than one day.
9931035\end {methoddesc }
9941036
9951037\begin {methoddesc }{dst}{}
9961038 If \member {tzinfo} is \code {None}, returns \code {None}, else
997- returns \code {tzinfo.dst(self)}.
1039+ returns \code {\var {self}.tzinfo.dst(None)}, and
1040+ raises an exception if the latter doesn't return \code {None}, or
1041+ a \class {timedelta} object representing a whole number of minutes
1042+ with magnitude less than one day.
9981043\end {methoddesc }
9991044
10001045\begin {methoddesc }{tzname}{}
10011046 If \member {tzinfo} is \code {None}, returns \code {None}, else
1002- returns \code {tzinfo.tzname(self)}.
1047+ returns \code {\var {self}.tzinfo.tzname(None)}, or
1048+ raises an exception if the latter doesn't return \code {None} or
1049+ a string object.
10031050\end {methoddesc }
10041051
10051052
@@ -1066,37 +1113,58 @@ \subsection{\class{tzinfo} Objects \label{datetime-tzinfo}}
10661113 example, \method {datetime.timetuple()} calls its \member {tzinfo}
10671114 member's \method {dst()} method to determine how the
10681115 \member {tm_isdst} flag should be set, and
1069- \method {datetime.astimezone ()} calls \method {dst()} to account for
1116+ \method {tzinfo.fromutc ()} calls \method {dst()} to account for
10701117 DST changes when crossing time zones.
10711118
10721119 An instance \var {tz} of a \class {tzinfo} subclass that models both
10731120 standard and daylight times must be consistent in this sense:
10741121
1075- \code {tz .utcoffset(dt ) - tz .dst(dt )}
1122+ \code {\var {tz} .utcoffset(\var {dt} ) - \var {tz} .dst(\var {dt} )}
10761123
10771124 must return the same result for every \class {datetime} \var {dt}
1078- with \code {dt.tzinfo==tz} For sane \class {tzinfo} subclasses, this
1079- expression yields the time zone's "standard offset" , which should not
1080- depend on the date or the time, but only on geographic location. The
1081- implementation of \method {datetime.astimezone()} relies on this, but
1082- cannot detect violations; it's the programmer's responsibility to
1083- ensure it.
1125+ with \code {\var {dt}.tzinfo==\var {tz}} For sane \class {tzinfo}
1126+ subclasses, this expression yields the time zone's "standard offset" ,
1127+ which should not depend on the date or the time, but only on geographic
1128+ location. The implementation of \method {datetime.astimezone()} relies
1129+ on this, but cannot detect violations; it's the programmer's
1130+ responsibility to ensure it. If a \class {tzinfo} subclass cannot
1131+ guarantee this, it may be able to override the default implementation
1132+ of \method {tzinfo.fromutc()} to work correctly with \method {astimezone()}
1133+ regardless.
1134+
1135+ Most implementations of \method {dst()} will probably look like one
1136+ of these two:
1137+
1138+ \begin {verbatim }
1139+ return timedelta(0) # a fixed-offset class: doesn't account for DST
1140+
1141+ or
1142+
1143+ # Code to set dston and dstoff to the time zone's DST transition
1144+ # times based on the input dt.year, and expressed in standard local
1145+ # time. Then
1146+
1147+ if dston <= dt.replace(tzinfo=None) < dstoff:
1148+ return timedelta(hours=1)
1149+ else:
1150+ return timedelta(0)
1151+ \end {verbatim }
10841152
10851153 The default implementation of \method {dst()} raises
10861154 \exception {NotImplementedError}.
10871155\end {methoddesc }
10881156
10891157\begin {methoddesc }{tzname}{self, dt}
1090- Return the timezone name corresponding to the \class {datetime}
1091- object represented
1092- by \var {dt}, as a string. Nothing about string names is defined by the
1093- \module {datetime} module, and there's no requirement that it mean anything
1094- in particular. For example, "GMT" , "UTC" , "-500" , "-5:00" , "EDT " ,
1095- "US/Eastern" , "America/New York" are all valid replies. Return
1158+ Return the time zone name corresponding to the \class {datetime}
1159+ object \var {dt}, as a string.
1160+ Nothing about string names is defined by the
1161+ \module {datetime} module, and there's no requirement that it mean
1162+ anything in particular. For example, "GMT" , "UTC" , "-500" , "-5:00" ,
1163+ "EDT" , " US/Eastern" , "America/New York" are all valid replies. Return
10961164 \code {None} if a string name isn't known. Note that this is a method
1097- rather than a fixed string primarily because some \class {tzinfo} objects
1098- will wish to return different names depending on the specific value
1099- of \var {dt} passed, especially if the \class {tzinfo} class is
1165+ rather than a fixed string primarily because some \class {tzinfo}
1166+ subclasses will wish to return different names depending on the specific
1167+ value of \var {dt} passed, especially if the \class {tzinfo} class is
11001168 accounting for daylight time.
11011169
11021170 The default implementation of \method {tzname()} raises
@@ -1113,7 +1181,7 @@ \subsection{\class{tzinfo} Objects \label{datetime-tzinfo}}
11131181When \code {None} is passed, it's up to the class designer to decide the
11141182best response. For example, returning \code {None} is appropriate if the
11151183class wishes to say that time objects don't participate in the
1116- \class {tzinfo} protocol . It may be more useful for \code {utcoffset(None)}
1184+ \class {tzinfo} protocols . It may be more useful for \code {utcoffset(None)}
11171185to return the standard UTC offset, as there is no other convention for
11181186discovering the standard offset.
11191187
@@ -1124,6 +1192,50 @@ \subsection{\class{tzinfo} Objects \label{datetime-tzinfo}}
11241192the \class {tzinfo} methods interpret \var {dt} as being in local time,
11251193and not need worry about objects in other timezones.
11261194
1195+ There is one more \class {tzinfo} method that a subclass may wish to
1196+ override:
1197+
1198+ \begin {methoddesc }{fromutc}{self, dt}
1199+ This is called from the default \class {datetime.astimezone()}
1200+ implementation. When called from that, \code {\var {dt}.tzinfo} is
1201+ \var {self}, and \var {dt}'s date and time members are to be viewed as
1202+ expressing a UTC time. The purpose of \method {fromutc()} is to
1203+ adjust the date and time members, returning an equivalent datetime in
1204+ \var {self}'s local time.
1205+
1206+ Most \class {tzinfo} subclasses should be able to inherit the default
1207+ \method {fromutc()} implementation without problems. It's strong enough
1208+ to handle fixed-offset time zones, and time zones accounting for both
1209+ standard and daylight time, and the latter even if the DST transition
1210+ times differ in different years. An example of a time zone the default
1211+ \method {fromutc()} implementation may not handle correctly in all cases
1212+ is one where the standard offset (from UTC) depends on the specific date
1213+ and time passed, which can happen for political reasons.
1214+ The default implementations of \method {astimezone()} and
1215+ \method {fromutc()} may not produce the result you want if the result is
1216+ one of the hours straddling the moment the standard offset changes.
1217+
1218+ Skipping code for error cases, the default \method {fromutc()}
1219+ implementation acts like:
1220+
1221+ \begin {verbatim }
1222+ def fromutc(self, dt):
1223+ # raise ValueError error if dt.tzinfo is not self
1224+ dtoff = dt.utcoffset()
1225+ dtdst = dt.dst()
1226+ # raise ValueError if dtoff is None or dtdst is None
1227+ delta = dtoff - dtdst # this is self's standard offset
1228+ if delta:
1229+ dt += delta # convert to standard local time
1230+ dtdst = dt.dst()
1231+ # raise ValueError if dtdst is None
1232+ if dtdst:
1233+ return dt + dtdst
1234+ else:
1235+ return dt
1236+ \end {verbatim }
1237+ \end {methoddesc }
1238+
11271239Example \class {tzinfo} classes:
11281240
11291241\verbatiminput {tzinfo-examples.py}
@@ -1150,7 +1262,7 @@ \subsection{\class{tzinfo} Objects \label{datetime-tzinfo}}
11501262day, so \code {astimezone(Eastern)} won't deliver a result with
11511263\code {hour==2} on the
11521264day DST begins. In order for \method {astimezone()} to make this
1153- guarantee, the \class {tzinfo} \ method {dst()} method must consider times
1265+ guarantee, the \method {rzinfo. dst()} method must consider times
11541266in the "missing hour" (2:MM for Eastern) to be in daylight time.
11551267
11561268When DST ends (the "end" line), there's a potentially worse problem:
@@ -1162,8 +1274,8 @@ \subsection{\class{tzinfo} Objects \label{datetime-tzinfo}}
11621274the local clock's behavior by mapping two adjacent UTC hours into the
11631275same local hour then. In the Eastern example, UTC times of the form
116412765:MM and 6:MM both map to 1:MM when converted to Eastern. In order for
1165- \method {astimezone()} to make this guarantee, the \class {tzinfo}
1166- \method {dst()} method must consider times in the "repeated hour" to be in
1277+ \method {astimezone()} to make this guarantee, the \method {tzinfo.dst() }
1278+ method must consider times in the "repeated hour" to be in
11671279standard time. This is easily arranged, as in the example, by expressing
11681280DST switch times in the time zone's standard local time.
11691281
@@ -1235,9 +1347,7 @@ \subsection{C API}
12351347
12361348 PyDateTime_Date
12371349 PyDateTime_DateTime
1238- PyDateTime_DateTimeTZ
12391350 PyDateTime_Time
1240- PyDateTime_TimeTZ
12411351 PyDateTime_Delta
12421352 PyDateTime_TZInfo
12431353
@@ -1249,15 +1359,9 @@ \subsection{C API}
12491359 PyDateTime_Check(op)
12501360 PyDateTime_CheckExact(op)
12511361
1252- PyDateTimeTZ_Check(op)
1253- PyDateTimeTZ_CheckExact(op)
1254-
12551362 PyTime_Check(op)
12561363 PyTime_CheckExact(op)
12571364
1258- PyTimeTZ_Check(op)
1259- PyTimeTZ_CheckExact(op)
1260-
12611365 PyDelta_Check(op)
12621366 PyDelta_CheckExact(op)
12631367
@@ -1269,18 +1373,18 @@ \subsection{C API}
12691373All objects are immutable, so accessors are read-only. All macros
12701374return ints:
12711375
1272- For \class {date}, \class {datetime}, and \class {datetimetz } instances:
1376+ For \class {date} and \class {datetime } instances:
12731377 PyDateTime_GET_YEAR(o)
12741378 PyDateTime_GET_MONTH(o)
12751379 PyDateTime_GET_DAY(o)
12761380
1277- For \class {datetime} and \class {datetimetz} instances:
1381+ For \class {datetime} instances:
12781382 PyDateTime_DATE_GET_HOUR(o)
12791383 PyDateTime_DATE_GET_MINUTE(o)
12801384 PyDateTime_DATE_GET_SECOND(o)
12811385 PyDateTime_DATE_GET_MICROSECOND(o)
12821386
1283- For \class {time} and \class {timetz} instances:
1387+ For \class {time} instances:
12841388 PyDateTime_TIME_GET_HOUR(o)
12851389 PyDateTime_TIME_GET_MINUTE(o)
12861390 PyDateTime_TIME_GET_SECOND(o)
0 commit comments