[Python-checkins] peps: PEP-0500: A protocol for delegating datetime methods

alexander.belopolsky python-checkins at python.org
Sun Aug 9 00:08:12 CEST 2015


https://hg.python.org/peps/rev/3ebed99e530f
changeset:   5941:3ebed99e530f
parent:      5937:7dc37e2dfb63
user:        Alexander Belopolsky <alexander.belopolsky at gmail.com>
date:        Sat Aug 08 18:07:27 2015 -0400
summary:
  PEP-0500: A protocol for delegating datetime methods

files:
  pep-0500.txt |  204 +++++++++++++++++++++++++++++++++++++++
  1 files changed, 204 insertions(+), 0 deletions(-)


diff --git a/pep-0500.txt b/pep-0500.txt
new file mode 100644
--- /dev/null
+++ b/pep-0500.txt
@@ -0,0 +1,204 @@
+PEP: 500
+Title: A protocol for delegating datetime methods to their
+       tzinfo implementations
+Version: $Revision$
+Last-Modified: $Date$
+Author: Alexander Belopolsky <alexander.belopolsky at gmail.com>
+Discussions-To: Datetime-SIG <datetime-sig at python.org>
+Status: Draft
+Type: Standards Track
+Content-Type: text/x-rst
+Requires: 495
+Created: 08-Aug-2015
+
+
+Abstract
+========
+
+This PEP specifies a new protocol (PDDM - "A Protocol for Delegating
+Datetime Methods") that can be used by concrete implementations of the
+``datetime.tzinfo`` interface to override aware datetime arithmetics,
+formatting and parsing.  We describe changes to the
+``datetime.datetime`` class to support the new protocol and propose a
+new abstract class ``datetime.tzstrict`` that implements parts of this
+protocol necessary to make aware datetime instances to follow "strict"
+arithmetic rules.
+
+
+Rationale
+=========
+
+As of Python 3.5, aware datetime instances that share a ``tzinfo``
+object follow the rules of arithmetics that are induced by a simple
+bijection between (year, month, day, hour, minute, second,
+microsecond) 7-tuples and large integers.  In this arithmetics, the
+difference between YEAR-11-02T12:00 and YEAR-11-01T12:00 is always 24
+hours, even though in the US/Eastern timezone, for example, there are
+25 hours between 2014-11-01T12:00 and 2014-11-02T12:00 because the
+local clocks were rolled back one hour at 2014-11-02T02:00,
+introducing an extra hour in the night between 2014-11-01 and
+2014-11-02.
+
+Many business applications requre the use of Python's simplified view
+of local dates.  No self-respecting car rental company will charge its
+customers more for a week that straddles the end of DST than for any
+other week or require that they return the car an hour early.
+Therefore, changing the current rules for aware datetime arithmentics
+will not only create a backward compatibility nightmare, it will
+eliminate support for legitimate and common use cases.
+
+Since it is impossible to choose universal rules for local time
+arithmetics, we propose to delegate implementation of those rules to
+the classes that implement ``datetime.tzinfo`` interface.  With such
+delegation in place, users will be able to choose between different
+arithmetics by simply picking instances of different classes for the
+value of ``tzinfo``.
+
+
+Protocol
+========
+
+Subtraction of datetime
+-----------------------
+
+A ``tzinfo`` subclass supporting the PDDM, may define a method called
+``__datetime_diff__`` that should take two ``datetime.datetime``
+instances and return a ``datetime.timedelta`` instance representing
+the time elapced from the time represented by the first datetime
+instance to another.
+
+
+Addition
+--------
+
+A ``tzinfo`` subclass supporting the PDDM, may define a method called
+``__datetime_add__`` that should take two arguments--a datetime and a
+timedelta instances--and return a datetime instance.
+
+
+Subtraction of timedelta
+------------------------
+
+A ``tzinfo`` subclass supporting the PDDM, may define a method called
+``__datetime_sub__`` that should take two arguments--a datetime and a
+timedelta instances--and return a datetime instance.
+ 
+
+Formatting
+----------
+
+A ``tzinfo`` subclass supporting the PDDM, may define methods called
+``__datetime_isoformat__`` and ``__datetime_strftime__``.
+
+The ``__datetime_isoformat__`` method should take a datetime instance
+and an optional separator and produce a string representation of the
+given datetime instance.
+
+The ``__datetime_strftime__`` method should take a datetime instance
+and a format string and produce a string representation of the given
+datetime instance formatted according to the given format.
+
+
+Parsing
+-------
+
+A ``tzinfo`` subclass supporting the PDDM, may define a class method
+called ``__datetime_strptime__`` and register the "canonical" names of
+the timezones that it implements with a registry. **TODO** Describe a
+registry.
+
+
+Changes to datetime methods
+===========================
+
+Subtraction
+-----------
+
+::
+
+   class datetime:
+       def __sub__(self, other):
+           if isinstance(other, datetime):
+               try:
+                   self_diff = self.tzinfo.__datetime_diff__
+               except AttributeError:
+                   self_diff = None
+               try:
+                   other_diff = self.tzinfo.__datetime_diff__
+               except AttributeError:
+                   other_diff = None
+               if self_diff is not None:
+                   if self_diff is not other_diff and self_diff.__func__ is not other_diff.__func__:
+                       raise ValueError("Cannot find difference of two datetimes with "
+                                        "different tzinfo.__datetime_diff__ implementations.")
+		   return self_diff(self, other)
+	   elif isinstance(other, timedelta):
+               try:
+                   sub = self.tzinfo.__datetime_sub__
+               except AttributeError:
+                   pass
+               else:
+                   return sub(self, other)
+               return self + -other
+           else:
+               return NotImplemented
+           # current implementation
+
+
+Addition
+--------
+
+Addition of a timedelta to a datetime instance will be delegated to the
+``self.tzinfo.__datetime_add__`` method whenever it is defined.
+
+
+Strict arithmetics
+==================
+
+A new abstract subclass of ``datetime.tzinfo`` class called  ``datetime.tzstrict``
+will be added to the ``datetime`` module.  This subclass will not implement the
+``utcoffset()``, ``tzname()`` or ``dst()`` methods, but will implement some of the
+methods of the PDDM.
+
+The PDDM methods implemented by ``tzstrict`` will be equivalent to the following::
+
+  class tzstrict(tzinfo):
+      def __datetime_diff__(self, dt1, dt2):
+          utc_dt1 = dt1.astimezone(timezone.utc)
+          utc_dt2 = dt2.astimezone(timezone.utc)
+	  return utc_dt2 - utc_dt1 
+
+      def __datetime_add__(self, dt, delta):
+          utc_dt = dt.astimezone(timezone.utc)
+	  return (utc_dt + delta).astimezone(self)
+
+      def __datetime_sub__(self, dt, delta):
+          utc_dt = dt.astimezone(timezone.utc)
+	  return (utc_dt - delta).astimezone(self)
+
+
+Parsing and formatting
+----------------------
+
+Datetime methods ``strftime`` and ``isoformat`` will delegate to the namesake
+methods of their ``tzinfo`` members whenever those methods are defined.
+
+When the ``datetime.strptime`` method is given a format string that
+contains a ``%Z`` instruction, it will lookup the ``tzinfo``
+implementation in the registry by the given timezone name and call its
+``__datetime_strptime__`` method.
+
+Applications
+============
+
+This PEP will enable third party implementation of many different
+timekeeping schemes including:
+
+* Julian / Microsoft Excel calendar.
+* "Right" timezones with the leap second support.
+* French revolutionary calendar (with a lot of work).
+
+Copyright
+=========
+
+This document has been placed in the public domain.

-- 
Repository URL: https://hg.python.org/peps


More information about the Python-checkins mailing list