A variety of small edits and clarifications to PEP 495.
This commit is contained in:
parent
c5bfd7e3d0
commit
32b6a542bd
74
pep-0495.txt
74
pep-0495.txt
|
@ -41,7 +41,7 @@ will enumerate the two ambiguous times.
|
|||
|
||||
.. [#] People who live in locations observing the Daylight Saving
|
||||
Time (DST) move their clocks back (usually one hour) every Fall.
|
||||
|
||||
|
||||
It is less common, but occasionally clocks can be moved back for
|
||||
other reasons. For example, Ukraine skipped the spring-forward
|
||||
transition in March 1990 and instead, moved their clocks back on
|
||||
|
@ -122,7 +122,11 @@ or 1, the new instance returned by ``replace()`` will have its
|
|||
``fold`` attribute set to that value. In CPython, any non-integer
|
||||
value of ``fold`` will raise a ``TypeError``, but other
|
||||
implementations may allow the value ``None`` to behave the same as
|
||||
when ``fold`` is not given. [#]_ If the ``fold`` argument is not
|
||||
when ``fold`` is not given. [#]_ (This is
|
||||
a nod to the existing difference in treatment of ``None`` arguments
|
||||
in other positions of this method across Python implementations;
|
||||
it is not intended to leave the door open for future alternative
|
||||
interpretation of ``fold=None``.) If the ``fold`` argument is not
|
||||
specified, the original value of the ``fold`` attribute is copied to
|
||||
the result.
|
||||
|
||||
|
@ -176,18 +180,23 @@ Affected Behaviors
|
|||
What time is it?
|
||||
................
|
||||
|
||||
The ``datetime.now()`` method called with no arguments, will set
|
||||
The ``datetime.now()`` method called without arguments will set
|
||||
``fold=1`` when returning the second of the two ambiguous times in a
|
||||
system local time fold. When called with a ``tzinfo`` argument, the
|
||||
value of the ``fold`` will be determined by the ``tzinfo.fromutc()``
|
||||
implementation. If an instance of the ``datetime.timezone`` class
|
||||
(*e.g.* ``datetime.timezone.utc``) is passed as ``tzinfo``, the
|
||||
implementation. When an instance of the ``datetime.timezone`` class
|
||||
(the stdlib's fixed-offset ``tzinfo`` subclass,
|
||||
*e.g.* ``datetime.timezone.utc``) is passed as ``tzinfo``, the
|
||||
returned datetime instance will always have ``fold=0``.
|
||||
The ``datetime.utcnow()`` method is unaffected.
|
||||
|
||||
|
||||
Conversion from naive to aware
|
||||
..............................
|
||||
|
||||
A new feature is proposed to facilitate conversion from naive datetime
|
||||
instances to aware.
|
||||
|
||||
The ``astimezone()`` method will now work for naive ``self``. The
|
||||
system local timezone will be assumed in this case and the ``fold``
|
||||
flag will be used to determine which local timezone is in effect
|
||||
|
@ -201,6 +210,11 @@ For example, on a system set to US/Eastern timezone::
|
|||
>>> dt.replace(fold=1).astimezone().strftime('%D %T %Z%z')
|
||||
'11/02/14 01:30:00 EST-0500'
|
||||
|
||||
An implication is that ``datetime.now(tz)`` is fully equivalent to
|
||||
``datetime.now().astimezone(tz)`` (assuming ``tz`` is an instance of a
|
||||
post-PEP ``tzinfo`` implementation, i.e. one that correctly handles
|
||||
and sets ``fold``).
|
||||
|
||||
|
||||
Conversion from POSIX seconds from EPOCH
|
||||
........................................
|
||||
|
@ -229,6 +243,8 @@ time, there are two values ``s0`` and ``s1`` such that::
|
|||
|
||||
datetime.fromtimestamp(s0) == datetime.fromtimestamp(s1) == dt
|
||||
|
||||
(This is because ``==`` disregards the value of fold -- see below.)
|
||||
|
||||
In this case, ``dt.timestamp()`` will return the smaller of ``s0``
|
||||
and ``s1`` values if ``dt.fold == 0`` and the larger otherwise.
|
||||
|
||||
|
@ -240,7 +256,6 @@ For example, on a system set to US/Eastern timezone::
|
|||
>>> datetime(2014, 11, 2, 1, 30, fold=1).timestamp()
|
||||
1414909800.0
|
||||
|
||||
|
||||
When a ``datetime.datetime`` instance ``dt`` represents a missing
|
||||
time, there is no value ``s`` for which::
|
||||
|
||||
|
@ -256,6 +271,8 @@ is always the same as the offset right after the gap.
|
|||
The value returned by ``dt.timestamp()`` given a missing
|
||||
``dt`` will be the greater of the two "nice to know" values
|
||||
if ``dt.fold == 0`` and the smaller otherwise.
|
||||
(This is not a typo -- it's intentionally backwards from the rule for
|
||||
ambiguous times.)
|
||||
|
||||
For example, on a system set to US/Eastern timezone::
|
||||
|
||||
|
@ -272,13 +289,14 @@ Users of pre-PEP implementations of ``tzinfo`` will not see any
|
|||
changes in the behavior of their aware datetime instances. Two such
|
||||
instances that differ only by the value of the ``fold`` attribute will
|
||||
not be distinguishable by any means other than an explicit access to
|
||||
the ``fold`` value.
|
||||
the ``fold`` value. (This is because these pre-PEP implementations
|
||||
are not using the ``fold`` attribute.)
|
||||
|
||||
On the other hand, if an object's ``tzinfo`` is set to a fold-aware
|
||||
implementation, then the value of ``fold`` will affect the result of
|
||||
several methods, but only if the corresponding time is in a fold or in
|
||||
a gap: ``utcoffset()``, ``dst()``, ``tzname()``, ``astimezone()``,
|
||||
``strftime()`` (if "%Z" or "%z" directive is used in the format
|
||||
implementation, then in a fold or gap the value of ``fold`` will
|
||||
affect the result of several methods:
|
||||
``utcoffset()``, ``dst()``, ``tzname()``, ``astimezone()``,
|
||||
``strftime()`` (if the "%Z" or "%z" directive is used in the format
|
||||
specification), ``isoformat()``, and ``timetuple()``.
|
||||
|
||||
|
||||
|
@ -300,8 +318,9 @@ with protocol version 4 (introduced in Python 3.4) or greater.
|
|||
|
||||
Pickle sizes for the ``datetime.datetime`` and ``datetime.time``
|
||||
objects will not change. The ``fold`` value will be encoded in the
|
||||
first bit of the 3rd (1st) byte of ``datetime.datetime``
|
||||
(``datetime.time``) pickle payload. In the `current implementation`_
|
||||
first bit of the 3rd byte of the ``datetime.datetime``
|
||||
pickle payload; and in the first bit of the 1st byte of the
|
||||
``datetime.time`` payload. In the `current implementation`_
|
||||
these bytes are used to store the month (1-12) and hour (0-23) values
|
||||
and the first bit is always 0. We picked these bytes because they are
|
||||
the only bytes that are checked by the current unpickle code. Thus
|
||||
|
@ -324,8 +343,11 @@ The basic implementation of ``fromutc()`` in the abstract
|
|||
``datetime.tzinfo`` class will not change. It is currently not used
|
||||
anywhere in the stdlib because the only included ``tzinfo``
|
||||
implementation (the ``datetime.timezone`` class implementing fixed
|
||||
offset timezones) override ``fromutc()``.
|
||||
|
||||
offset timezones) override ``fromutc()``. Keeping the default
|
||||
implementation unchanged has the benefit that pre-PEP 3rd party
|
||||
implementations that inherit the default ``fromutc()`` are not
|
||||
accidentally affected.
|
||||
|
||||
|
||||
Guidelines for New tzinfo Implementations
|
||||
=========================================
|
||||
|
@ -381,7 +403,7 @@ Mind the Gap
|
|||
|
||||
The ``fromutc()`` method should never produce a time in the gap.
|
||||
|
||||
If ``utcoffset()``, ``tzname()`` or ``dst()`` method is called on a
|
||||
If the ``utcoffset()``, ``tzname()`` or ``dst()`` method is called on a
|
||||
local time that falls in a gap, the rules in effect before the
|
||||
transition should be used if ``fold=0``. Otherwise, the rules in
|
||||
effect after the transition should be used.
|
||||
|
@ -477,7 +499,7 @@ with naive datetime instances. As a consequence, naive
|
|||
by the value of ``fold`` will compare as equal. Applications that
|
||||
need to differentiate between such instances should check the value of
|
||||
``fold`` explicitly or convert those instances to a timezone that does
|
||||
not have ambiguous times.
|
||||
not have ambiguous times (such as UTC).
|
||||
|
||||
The value of ``fold`` will also be ignored whenever a timedelta is
|
||||
added to or subtracted from a datetime instance which may be either
|
||||
|
@ -495,7 +517,9 @@ previous paragraph, timedelta addition ignores both ``fold`` and
|
|||
subtraction.
|
||||
|
||||
Naive and intra-zone comparisons will ignore the value of ``fold`` and
|
||||
return the same results as they do now.
|
||||
return the same results as they do now. (This is the only way to
|
||||
preserve backward compatibility. If you need an aware intra-zone
|
||||
comparison that uses the fold, convert both sides to UTC first.)
|
||||
|
||||
The inter-zone subtraction will be defined as it is now: ``t - s`` is
|
||||
computed as ``(t - t.utcoffset()) - (s -
|
||||
|
@ -506,14 +530,14 @@ depend on the values of ``t.fold`` and ``s.fold`` when either
|
|||
.. [#] Note that the new rules may result in a paradoxical situation
|
||||
when ``s == t`` but ``s - u != t - u``. Such paradoxes are
|
||||
not really new and are inherent in the overloading of the minus
|
||||
operator as two different intra- and inter-zone operations. For
|
||||
operator differently for intra- and inter-zone operations. For
|
||||
example, one can easily construct datetime instances ``t`` and ``s``
|
||||
with some variable offset ``tzinfo`` and a datetime ``u`` with
|
||||
``tzinfo=timezone.utc`` such that ``(t - u) - (s - u) != t - s``.
|
||||
The explanation for this paradox is that the minuses inside the
|
||||
parentheses and the two other minuses are really three different
|
||||
operations: inter-zone datetime subtraction, timedelta subtraction
|
||||
and intra-zone datetime subtraction which have the mathematical
|
||||
operations: inter-zone datetime subtraction, timedelta subtraction,
|
||||
and intra-zone datetime subtraction, which each have the mathematical
|
||||
properties of subtraction separately, but not when combined in a
|
||||
single expression.
|
||||
|
||||
|
@ -522,9 +546,9 @@ Aware datetime Equality Comparison
|
|||
----------------------------------
|
||||
|
||||
The aware datetime comparison operators will work the same as they do
|
||||
now with results indirectly affected by the value of ``fold`` whenever
|
||||
``utcoffset()`` value of one of the operands depends on it, with one
|
||||
exception. Whenever one of the operands in inter-zone comparison is
|
||||
now, with results indirectly affected by the value of ``fold`` whenever
|
||||
the ``utcoffset()`` value of one of the operands depends on it, with one
|
||||
exception. Whenever one or both of the operands in inter-zone comparison is
|
||||
such that its ``utcoffset()`` depends on the value of its ``fold``
|
||||
fold attribute, the result is ``False``. [#]_
|
||||
|
||||
|
@ -541,7 +565,7 @@ value of ``fold``:
|
|||
|
||||
def toutc(t, fold):
|
||||
u = t - t.replace(fold=fold).utcoffset()
|
||||
return u.replace(tzinfo=None)
|
||||
return u.replace(tzinfo=None)
|
||||
|
||||
Then ``t == s`` is equivalent to
|
||||
|
||||
|
|
Loading…
Reference in New Issue