类似于datetime.timedelta,用于日期算术。
项目描述
datedelta.datedelta 是 datetime.timedelta 用于日期算术。
>>> import datetime
>>> import datedelta
>>> datetime.date(2025, 4, 22) + 2 * datedelta.WEEK
datetime.date(2025, 5, 6)
>>> datetime.date(2025, 4, 22) + 3 * datedelta.MONTH
datetime.date(2025, 7, 22)
它考虑了格里高利日历的奇异性。
>>> datetime.date(2024, 2, 29) + datedelta.YEAR
datetime.date(2025, 3, 1)
>>> datetime.date(2024, 2, 29) + 4 * datedelta.YEAR
datetime.date(2028, 2, 29)
它方便计算年度、月度或周订阅周期。
>>> start_date = datetime.date(2024, 1, 30)
>>> for n in range(12):
... print(repr(start_date + n * datedelta.MONTH))
datetime.date(2024, 1, 30)
datetime.date(2024, 3, 1)
datetime.date(2024, 3, 30)
datetime.date(2024, 4, 30)
datetime.date(2024, 5, 30)
datetime.date(2024, 6, 30)
datetime.date(2024, 7, 30)
datetime.date(2024, 8, 30)
datetime.date(2024, 9, 30)
datetime.date(2024, 10, 30)
datetime.date(2024, 11, 30)
datetime.date(2024, 12, 30)
>>> start_date = datetime.date(2024, 1, 31)
>>> for n in range(12):
... print(repr(start_date + n * datedelta.MONTH))
datetime.date(2024, 1, 31)
datetime.date(2024, 3, 1)
datetime.date(2024, 3, 31)
datetime.date(2024, 5, 1)
datetime.date(2024, 5, 31)
datetime.date(2024, 7, 1)
datetime.date(2024, 7, 31)
datetime.date(2024, 8, 31)
datetime.date(2024, 10, 1)
datetime.date(2024, 10, 31)
datetime.date(2024, 12, 1)
datetime.date(2024, 12, 31)
它保证它支持的算术操作结果一致。
行为
格里高利日历中有两个日期算术陷阱
闰年。当将年份加到2月29日时,如果结果是平年,则会出问题。
月份中天数不同。当将月份加到29日、30日或31日时,如果结果是那个月不存在的那一天,则会出问题。
在这两种情况下,datedelta将结果更改为下一个月的第一天。
如果周期以(起始日期包含,结束日期排除)表示——如果你喜欢数学符号,那就是[start date, end date),这种方法给出的结果是一致的。这种周期表示类似于0索引,这是Python使用的约定。
例如
如果某人在2020-02-29(包含)开始订阅一年,则结束日期必须是2021-03-01(排除)。如果它是2020-02-28(排除),则那天将从订阅周期中缺失。
如果某人在2020-03-31(包含)开始订阅三个月,则结束日期必须是2020-07-01(排除)。如果它是2020-06-30(排除),则那天将从订阅周期中缺失。
操作总是按年、月、日的顺序执行。这种顺序通常提供预期的行为。它还可以最小化精度损失。
安装
pip install datedelta
使用
最常见的操作是将 datedelta 添加到日期,以及从日期中减去 datedelta。
基本间隔
YEAR、MONTH、WEEK 和 DAY 常量支持使用少量代码进行常见计算。
>>> import datetime
>>> import datedelta
>>> datetime.date(2022, 1, 1) + datedelta.YEAR
datetime.date(2023, 1, 1)
>>> datetime.date(2023, 1, 1) - datedelta.YEAR
datetime.date(2022, 1, 1)
>>> datetime.date(2024, 2, 29) + datedelta.YEAR
datetime.date(2025, 3, 1)
>>> datetime.date(2025, 3, 1) - datedelta.YEAR
datetime.date(2024, 3, 1)
>>> datetime.date(2022, 1, 1) + datedelta.MONTH
datetime.date(2022, 2, 1)
>>> datetime.date(2022, 2, 1) - datedelta.MONTH
datetime.date(2022, 1, 1)
>>> datetime.date(2022, 1, 31) + datedelta.MONTH
datetime.date(2022, 3, 1)
>>> datetime.date(2022, 3, 1) - datedelta.MONTH
datetime.date(2022, 2, 1)
>>> datetime.date(2022, 1, 1) + datedelta.WEEK
datetime.date(2022, 1, 8)
>>> datetime.date(2022, 1, 1) - datedelta.WEEK
datetime.date(2021, 12, 25)
>>> datetime.date(2022, 1, 1) + datedelta.DAY
datetime.date(2022, 1, 2)
>>> datetime.date(2022, 1, 1) - datedelta.DAY
datetime.date(2021, 12, 31)
datedelta.DAY 的行为与 datetime.timedelta(1) 完全相同。它仅提供以保持一致性。
任意间隔
datedelta 对象提供对任意计算的支持。
>>> import datetime
>>> import datedelta
>>> datetime.date(2022, 3, 23) + datedelta.datedelta(years=1, months=1, days=-1)
datetime.date(2023, 4, 22)
>>> datetime.date(2022, 3, 23) - datedelta.datedelta(years=-1, months=-1, days=1)
datetime.date(2023, 4, 22)
>>> datetime.date(2024, 2, 29) + datedelta.datedelta(years=2)
datetime.date(2026, 3, 1)
>>> datetime.date(2024, 2, 29) - datedelta.datedelta(years=2)
datetime.date(2022, 3, 1)
>>> datetime.date(2024, 2, 29) + datedelta.datedelta(years=2, days=-1)
datetime.date(2026, 2, 28)
>>> datetime.date(2024, 2, 29) - datedelta.datedelta(years=2, days=1)
datetime.date(2022, 2, 28)
>>> datetime.date(2024, 2, 29) + datedelta.datedelta(years=2, months=6)
datetime.date(2026, 9, 1)
>>> datetime.date(2024, 2, 29) - datedelta.datedelta(years=2, months=-6)
datetime.date(2022, 9, 1)
>>> datetime.date(2024, 2, 29) + datedelta.datedelta(years=4)
datetime.date(2028, 2, 29)
>>> datetime.date(2024, 2, 29) - datedelta.datedelta(years=4)
datetime.date(2020, 2, 29)
>>> datetime.date(2024, 2, 29) + datedelta.datedelta(years=4, days=1)
datetime.date(2028, 3, 1)
>>> datetime.date(2024, 2, 29) - datedelta.datedelta(years=4, days=-1)
datetime.date(2020, 3, 1)
>>> datetime.date(2024, 2, 29) + datedelta.datedelta(years=4, months=6)
datetime.date(2028, 8, 29)
>>> datetime.date(2024, 2, 29) - datedelta.datedelta(years=4, months=-6)
datetime.date(2020, 8, 29)
这些结果与上述“行为”中解释的数学上一致。
其他操作
datedelta 实例可以与整数相加、相减和相乘。但是,在加法和减法方面有一些限制。
将给定的 datedelta 添加到日期并从中减去,并不总是返回原始日期。为了防止由此行为引起的错误,当添加或减去两个 datedelta 的结果不明确时,会引发一个 ValueError。
>>> import datedelta
>>> datedelta.YEAR + datedelta.YEAR
datedelta.datedelta(years=2)
>>> 3 * datedelta.YEAR
datedelta.datedelta(years=3)
>>> datedelta.YEAR - datedelta.DAY
datedelta.datedelta(years=1, days=-1)
>>> datedelta.YEAR - datedelta.YEAR
Traceback (most recent call last):
...
ValueError: cannot subtract datedeltas with same signs
>>> datedelta.datedelta(months=6) + datedelta.datedelta(months=-3)
Traceback (most recent call last):
...
ValueError: cannot add datedeltas with opposite signs
限制
涉及 datedelta 的加法在一般情况下既不具有结合性也不具有交换性。
以下两个例子表明,添加 datedelta 然后减去它并不总是返回原始值
>>> import datetime
>>> import datedelta
>>> datetime.date(2024, 2, 29) + datedelta.datedelta(years=1)
datetime.date(2025, 3, 1)
>>> datetime.date(2025, 3, 1) - datedelta.datedelta(years=1)
datetime.date(2024, 3, 1)
>>> datetime.date(2024, 1, 31) + datedelta.datedelta(months=1)
datetime.date(2024, 3, 1)
>>> datetime.date(2024, 3, 1) - datedelta.datedelta(months=1)
datetime.date(2024, 2, 1)
以下两个例子表明,添加两个 datedelta 的结果取决于操作顺序
>>> import datetime
>>> import datedelta
>>> datetime.date(2024, 2, 29) + datedelta.datedelta(months=6) + datedelta.datedelta(years=1)
datetime.date(2025, 8, 29)
>>> datetime.date(2024, 2, 29) + datedelta.datedelta(years=1) + datedelta.datedelta(months=6)
datetime.date(2025, 9, 1)
>>> datetime.date(2024, 1, 31) + datedelta.datedelta(months=2) + datedelta.datedelta(months=5)
datetime.date(2024, 8, 31)
>>> datetime.date(2024, 1, 31) + datedelta.datedelta(months=5) + datedelta.datedelta(months=2)
datetime.date(2024, 9, 1)
为了避免问题,您应该始终从相同的参考日期开始,并添加单个 datedelta。不要链式添加或减去。
为了最小化错误结果的风险,datedelta 只实现了具有明确语义的操作
将 datedelta 添加到日期
从日期中减去 datedelta
当组成部分具有相同符号时,将 datedelta 添加到 datedelta
当组成部分具有相反符号时,从 datedelta 中减去 datedelta
(PEP 20 说:“面对歧义,拒绝猜测的诱惑。”)
替代方案
datedelta.datedelta 比标准的 datetime.timedelta 更智能,因为它了解除了天以外还有年和月。
与 pendulum.Duration 或 dateutil.relativedelta.relativedelta 相比,datedelta.datedelta 有一些优点
它以一种数学上一致的方式处理非现有结果:它调整到下一个月的第一天,而 pendulum 和 dateutil 调整到当前月的最后一天。
它提供了一个旨在防止编程错误的 API:它要求关键字参数,拒绝表达不正确业务逻辑的操作,并省略了 dateutil 中的易出错的特性,如“替换”行为或对闰日的显式控制。
它具有非常小的内存占用,因为它提供了 pendulum 或 dateutil 中非常小的功能子集。这使得它在您对标准库的 datetime 模块感到满意的情况下成为一个不错的选择。
变更日志
1.3
添加 WEEK 常量。
1.2
优化哈希和序列化。
1.1
添加 YEAR、MONTH 和 DAY 常量。
1.0
初始稳定版本。
项目详情
下载文件
下载适合您平台的文件。如果您不确定选择哪个,请了解有关安装包的更多信息。
源代码分发
构建分发
datedelta-1.4.tar.gz的哈希值
算法 | 哈希摘要 | |
---|---|---|
SHA256 | 3f1ef319ead642a76a3cab731917bf14a0ced0d91943f33ff57ae615837cab97 |
|
MD5 | c587ea0c2a39b0942795eae9e3601240 |
|
BLAKE2b-256 | b15da34fd53137d287fd08182d9530941f651a88de67bddc68292954166355e0 |
datedelta-1.4-py3-none-any.whl的哈希值
算法 | 哈希摘要 | |
---|---|---|
SHA256 | 9f7a8a2bd80d29d6cfe1036990979ea404c8e1ddbc5a73cff74d283186d12b4d |
|
MD5 | b730c3a1f0d5754644bb2dcde0024e9b |
|
BLAKE2b-256 | 580472573efc775afde1c0a69f30e1f0f5585fee421a6abf1bec5eefec5980ec |