Following system colour scheme - Python 增强提案 Selected dark colour scheme - Python 增强提案 Selected light colour scheme - Python 增强提案

Python增强提案

PEP 500 – 将 datetime 方法委托给其 tzinfo 实现的协议

作者:
Alexander Belopolsky <alexander.belopolsky at gmail.com>,Tim Peters <tim.peters at gmail.com>
讨论邮件列表:
Datetime-SIG 邮件列表
状态:
已拒绝
类型:
标准跟踪
依赖:
495
创建日期:
2015年8月8日
决议:
Datetime-SIG 邮件

目录

摘要

本 PEP 指定了一个新的协议(PDDM - “将日期时间方法委托给其 tzinfo 实现的协议”),可供 datetime.tzinfo 接口的具体实现用于覆盖感知日期时间的算术运算、格式化和解析。我们描述了对 datetime.datetime 类的更改以支持新协议,并提出一个新的抽象类 datetime.tzstrict,该类实现了使感知日期时间实例遵循“严格”算术规则所需的部分协议。

基本原理

从 Python 3.5 开始,共享 tzinfo 对象的感知日期时间实例遵循由 (year, month, day, hour, minute, second, microsecond) 7 元组与大整数之间简单双射引起的算术规则。在这种算术运算中,YEAR-11-02T12:00 和 YEAR-11-01T12:00 之间的差值始终为 24 小时,即使在 US/Eastern 时区中,例如,2014-11-01T12:00 和 2014-11-02T12:00 之间有 25 小时,因为本地时钟在 2014-11-02T02:00 回拨了一小时,在 2014-11-01 和 2014-11-02 之间的夜晚增加了一个小时。

许多商业应用程序需要使用 Python 对本地日期的简化视图。任何有尊严的租车公司都不会因为跨越夏令时结束的一周而向客户收取更多费用,也不会要求他们提前一小时还车。因此,更改感知日期时间算术的当前规则不仅会造成向后兼容性问题,还会消除对合法且常见用例的支持。

由于无法为本地时间算术选择通用规则,因此我们建议将这些规则的实现委托给实现 datetime.tzinfo 接口的类。有了这样的委托,用户只需选择不同类的实例作为 tzinfo 的值,即可在不同的算术运算之间进行选择。

协议

datetime的减法

支持 PDDM 的 tzinfo 子类可以定义一个名为 __datetime_diff__ 的方法,该方法应接受两个 datetime.datetime 实例并返回一个 datetime.timedelta 实例,表示从第一个 datetime 实例表示的时间到另一个时间经过的时间。

加法

支持 PDDM 的 tzinfo 子类可以定义一个名为 __datetime_add__ 的方法,该方法应接受两个参数——一个 datetime 实例和一个 timedelta 实例——并返回一个 datetime 实例。

timedelta的减法

支持 PDDM 的 tzinfo 子类可以定义一个名为 __datetime_sub__ 的方法,该方法应接受两个参数——一个 datetime 实例和一个 timedelta 实例——并返回一个 datetime 实例。

格式化

支持 PDDM 的 tzinfo 子类可以定义名为 __datetime_isoformat____datetime_strftime__ 的方法。

__datetime_isoformat__ 方法应接受一个 datetime 实例和一个可选的分隔符,并生成给定 datetime 实例的字符串表示形式。

__datetime_strftime__ 方法应接受一个 datetime 实例和一个格式字符串,并生成给定 datetime 实例的字符串表示形式,该字符串根据给定的格式进行格式化。

解析

支持 PDDM 的 tzinfo 子类可以定义一个名为 __datetime_strptime__ 的类方法,并在注册表中注册其实现的时区的“规范”名称。**待办事项** 描述注册表。

对 datetime 方法的更改

减法

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

加法

将 timedelta 添加到 datetime 实例将委托给 self.tzinfo.__datetime_add__ 方法(只要该方法已定义)。

严格算术

将向 datetime 模块添加一个名为 datetime.tzstrictdatetime.tzinfo 类的新抽象子类。此子类不会实现 utcoffset()tzname()dst() 方法,但会实现 PDDM 的一些方法。

tzstrict 实现的 PDDM 方法将等效于以下内容

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)

解析和格式化

Datetime 方法 strftimeisoformat 将委托给其 tzinfo 成员的同名方法(只要这些方法已定义)。

datetime.strptime 方法获得包含 %Z 指令的格式字符串时,它将通过给定的时区名称在注册表中查找 tzinfo 实现,并调用其 __datetime_strptime__ 方法。

应用

此 PEP 将使第三方能够实现许多不同的时间保存方案,包括

  • 儒略历/Microsoft Excel 日历。
  • 支持闰秒的“正确”时区。
  • 法国革命历法(需要大量工作)。

来源:https://github.com/python/peps/blob/main/peps/pep-0500.rst

上次修改时间:2023年9月9日17:39:29 GMT