mirror of https://github.com/python/cpython
datetime_from_timet_and_us(): ignore leap seconds if the platform
localtime()/gmtime() insists on delivering them, + associated doc changes. Redid the docs for datetimtez.astimezone().
This commit is contained in:
parent
85e4c6757f
commit
75a6e3bd1a
|
@ -314,8 +314,9 @@ Other constructors, all class methods:
|
||||||
\exception{ValueError}, if the timestamp is out of the range of
|
\exception{ValueError}, if the timestamp is out of the range of
|
||||||
values supported by the platform C \cfunction{localtime()}
|
values supported by the platform C \cfunction{localtime()}
|
||||||
function. It's common for this to be restricted to years from 1970
|
function. It's common for this to be restricted to years from 1970
|
||||||
through 2038.
|
through 2038. Note that on non-POSIX systems that include leap
|
||||||
\end{methoddesc}
|
seconds in their notion of a timestamp, leap seconds are ignored by
|
||||||
|
\method{fromtimestamp()}.
|
||||||
|
|
||||||
\begin{methoddesc}{fromordinal}{ordinal}
|
\begin{methoddesc}{fromordinal}{ordinal}
|
||||||
Return the date corresponding to the proleptic Gregorian ordinal,
|
Return the date corresponding to the proleptic Gregorian ordinal,
|
||||||
|
@ -546,6 +547,11 @@ Other constructors, all class methods:
|
||||||
range of values supported by the platform C
|
range of values supported by the platform C
|
||||||
\cfunction{localtime()} function. It's common for this to be
|
\cfunction{localtime()} function. It's common for this to be
|
||||||
restricted to years in 1970 through 2038.
|
restricted to years in 1970 through 2038.
|
||||||
|
Note that on non-POSIX systems that include leap seconds in their
|
||||||
|
notion of a timestamp, leap seconds are ignored by
|
||||||
|
\method{fromtimestamp()}, and then it's possible to have two timestamps
|
||||||
|
differing by a second that yield identical \class{datetime} objects.
|
||||||
|
\end{methoddesc}
|
||||||
See also \method{utcfromtimestamp()}.
|
See also \method{utcfromtimestamp()}.
|
||||||
\end{methoddesc}
|
\end{methoddesc}
|
||||||
|
|
||||||
|
@ -988,16 +994,18 @@ April, and ends the minute after 1:59 (EDT) on the last Sunday in October:
|
||||||
|
|
||||||
When DST starts (the "start" line), the local wall clock leaps from 1:59
|
When DST starts (the "start" line), the local wall clock leaps from 1:59
|
||||||
to 3:00. A wall time of the form 2:MM doesn't really make sense on that
|
to 3:00. A wall time of the form 2:MM doesn't really make sense on that
|
||||||
day, so astimezone(Eastern) won't deliver a result with hour=2 on the
|
day, so \code{astimezone(Eastern)} won't deliver a result with
|
||||||
day DST begins. How an Eastern class chooses to interpret 2:MM on
|
\code{hour==2} on the
|
||||||
that day is its business. The example Eastern class above chose to
|
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
|
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.
|
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
|
Your Eastern class may wish, for example, to raise an exception instead
|
||||||
when it sees a 2:MM time on the day Eastern begins.
|
when it sees a 2:MM time on the day EDT begins.
|
||||||
|
|
||||||
When DST ends (the "end" line), there's a potentially worse problem:
|
When DST ends (the "end" line), there's a potentially worse problem:
|
||||||
there's an hour that can't be spelled at all in local wall time, the
|
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
|
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
|
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.
|
leaps from 1:59 (daylight time) back to 1:00 (standard time) again.
|
||||||
|
@ -1005,11 +1013,12 @@ leaps from 1:59 (daylight time) back to 1:00 (standard time) again.
|
||||||
2:MM is taken as standard time (it's "after 2:00"), so maps to 7: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.
|
There is no local time that maps to 6:MM UTC on this day.
|
||||||
|
|
||||||
Just as the wall clock does, astimezone(Eastern) maps both UTC hours 5:MM
|
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
|
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
|
ambiguous (there's no way for Eastern to know which repetition of 1:MM
|
||||||
is intended). Applications that can't bear such ambiguity even one hour
|
is intended). Applications that can't bear such ambiguity
|
||||||
per year should avoid using hybrid tzinfo classes; there are no
|
should avoid using hybrid tzinfo classes; there are no
|
||||||
ambiguities when using UTC, or any other fixed-offset tzinfo subclass
|
ambiguities when using UTC, or any other fixed-offset tzinfo subclass
|
||||||
(such as a class representing only EST (fixed offset -5 hours), or only
|
(such as a class representing only EST (fixed offset -5 hours), or only
|
||||||
EDT (fixed offset -4 hours)).
|
EDT (fixed offset -4 hours)).
|
||||||
|
@ -1354,19 +1363,24 @@ Instance methods:
|
||||||
\end{methoddesc}
|
\end{methoddesc}
|
||||||
|
|
||||||
\begin{methoddesc}{astimezone}{tz}
|
\begin{methoddesc}{astimezone}{tz}
|
||||||
Return a \class{datetimetz} with new tzinfo member \var{tz}. \var{tz}
|
Return a \class{datetimetz} object with new \membar{tzinfo} member
|
||||||
must be \code{None}, or an instance of a \class{tzinfo} subclass. If
|
\var{tz}.
|
||||||
\var{tz} is \code{None}, self is naive, or
|
\var{tz} must be \code{None}, or an instance of a \class{tzinfo} subclass.
|
||||||
|
If \var{tz} is \code{None}, \var{self} is naive,
|
||||||
\code{tz.utcoffset(self)} returns \code{None},
|
\code{tz.utcoffset(self)} returns \code{None},
|
||||||
|
or \code{self.tzinfo}\ is \var{tz},
|
||||||
\code{self.astimezone(tz)} is equivalent to
|
\code{self.astimezone(tz)} is equivalent to
|
||||||
\code{self.replace(tzinfo=tz)}: a new timezone object is attached
|
\code{self.replace(tzinfo=tz)}: a new timezone object is attached
|
||||||
without any conversion of date or time fields. If self is aware and
|
without any conversion of date or time fields. Else \code{self.tzinfo}
|
||||||
\code{tz.utcoffset(self)} does not return \code{None}, the date and
|
and \var{tz} must implement the \method{utcoffset()} and \method{dst()}
|
||||||
time fields are adjusted so that the result is local time in timezone
|
\class{tzinfo} methods, and the date and time fields are adjusted so
|
||||||
tz, representing the same UTC time as self.
|
that the result is local time in time zone \var{tz}, representing the
|
||||||
XXX [The treatment of endcases remains unclear: for DST-aware
|
same UTC time as \var{self}: after \code{astz = dt.astimezone(tz)},
|
||||||
classes, one hour per year has two spellings in local time, and
|
\code{astz - astz.utcoffset()} will usually have the same date and time
|
||||||
another hour has no spelling in local time.] XXX
|
members as \code{dt - dt.utcoffset()}. The discussion of class
|
||||||
|
\class{tzinfo} explains the cases at Daylight Saving Time
|
||||||
|
transition boundaries where this cannot be achieved (an issue only if
|
||||||
|
\var{tz} models both standard and daylight time).
|
||||||
\end{methoddesc}
|
\end{methoddesc}
|
||||||
|
|
||||||
\begin{methoddesc}{utcoffset}{}
|
\begin{methoddesc}{utcoffset}{}
|
||||||
|
|
|
@ -50,6 +50,12 @@ Extension modules
|
||||||
time), this case can arise one hour per year, at the hour daylight time
|
time), this case can arise one hour per year, at the hour daylight time
|
||||||
ends. See new docs for details.
|
ends. See new docs for details.
|
||||||
|
|
||||||
|
The constructors building a datetime from a timestamp could raise
|
||||||
|
ValueError if the platform C localtime()/gmtime() inserted "leap
|
||||||
|
seconds". Leap seconds are ignored now. On such platforms, it's
|
||||||
|
possible to have timestamps that differ by a second, yet where
|
||||||
|
datetimes constructed from them are equal.
|
||||||
|
|
||||||
Library
|
Library
|
||||||
-------
|
-------
|
||||||
|
|
||||||
|
|
|
@ -2831,7 +2831,15 @@ datetime_from_timet_and_us(PyObject *cls, TM_FUNC f, time_t timet, int us)
|
||||||
PyObject *result = NULL;
|
PyObject *result = NULL;
|
||||||
|
|
||||||
tm = f(&timet);
|
tm = f(&timet);
|
||||||
if (tm)
|
if (tm) {
|
||||||
|
/* The platform localtime/gmtime may insert leap seconds,
|
||||||
|
* indicated by tm->tm_sec > 59. We don't care about them,
|
||||||
|
* except to the extent that passing them on to the datetime
|
||||||
|
* constructor would raise ValueError for a reason that
|
||||||
|
* made no sense to the user.
|
||||||
|
*/
|
||||||
|
if (tm->tm_sec > 59)
|
||||||
|
tm->tm_sec = 59;
|
||||||
result = PyObject_CallFunction(cls, "iiiiiii",
|
result = PyObject_CallFunction(cls, "iiiiiii",
|
||||||
tm->tm_year + 1900,
|
tm->tm_year + 1900,
|
||||||
tm->tm_mon + 1,
|
tm->tm_mon + 1,
|
||||||
|
@ -2840,6 +2848,7 @@ datetime_from_timet_and_us(PyObject *cls, TM_FUNC f, time_t timet, int us)
|
||||||
tm->tm_min,
|
tm->tm_min,
|
||||||
tm->tm_sec,
|
tm->tm_sec,
|
||||||
us);
|
us);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
PyErr_SetString(PyExc_ValueError,
|
PyErr_SetString(PyExc_ValueError,
|
||||||
"timestamp out of range for "
|
"timestamp out of range for "
|
||||||
|
|
Loading…
Reference in New Issue