首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何在python中为datetime.date对象添加"3个月“?

如何在python中为datetime.date对象添加"3个月“?
EN

Stack Overflow用户
提问于 2012-03-07 08:54:58
回答 7查看 66.4K关注 0票数 38

Python日期计算,你在哪里?

我有一个python应用程序,它需要在几年内每三个月绘制一次日期。重要的是日期在一年中恰好出现4次,并且日期尽可能出现在每年的同一天,日期尽可能出现在月份的同一天,并且日期尽可能地接近"3个月“(这是一个移动的目标,特别是在闰年)。不幸的是,datetime.timedelta不支持月份!

在python中有没有“标准”的计算方法?

SQL方式?

如果最坏的情况发生,我会用平底船,让我的应用程序向PostgreSQL询问,他确实有很好的内置日期计算支持,答案如下:

代码语言:javascript
运行
复制
# select ('2010-11-29'::date + interval '3 months')::date;
    date    
------------
 2011-02-28
(1 row)
EN

回答 7

Stack Overflow用户

回答已采纳

发布于 2012-03-07 09:42:23

如果你正在寻找确切的或“更精确”的日期,你可能更好地查看dateutil

快速示例:

代码语言:javascript
运行
复制
>>> from dateutil.relativedelta import relativedelta
>>> import datetime
>>> TODAY = datetime.date.today()
>>> TODAY
datetime.date(2012, 3, 6)

现在将TODAY添加3个月,观察到它与日期完全匹配(请注意,relativedelta(months=3)relativedelta(month=3)具有不同的行为。确保在这些示例中使用months!)。

代码语言:javascript
运行
复制
>>> three_mon_rel = relativedelta(months=3)
>>> TODAY + three_mon_rel
datetime.date(2012, 6, 6)

并且在一年的过程中保持一致。从字面上讲,每三个月,在这一天(必须不断添加,因为出于某种原因,将relativedelta相乘并将其添加到datetime.date对象会抛出TypeError):

代码语言:javascript
运行
复制
>>> TODAY + three_mon_rel + three_mon_rel
datetime.date(2012, 9, 6)
>>> TODAY + three_mon_rel + three_mon_rel + three_mon_rel
datetime.date(2012, 12, 6)
>>> TODAY + three_mon_rel + three_mon_rel + three_mon_rel + three_mon_rel
datetime.date(2013, 3, 6)

mVChr的建议解决方案,虽然绝对“足够好”,但随着时间的推移略有变化:

代码语言:javascript
运行
复制
>>> three_mon_timedelta = datetime.timedelta(days=3 * 365/12)
>>> TODAY + three_mon_timedelta
datetime.date(2012, 6, 5)

在一年的过程中,月份中的某一天一直在滑动:

代码语言:javascript
运行
复制
>>> TODAY + three_mon_timedelta * 2
datetime.date(2012, 9, 4)
>>> TODAY + three_mon_timedelta * 3
datetime.date(2012, 12, 4)
>>> TODAY + three_mon_timedelta * 4
datetime.date(2013, 3, 5)
票数 77
EN

Stack Overflow用户

发布于 2012-03-07 09:11:13

代码语言:javascript
运行
复制
import datetime

some_date = datetime.date.today()
three_months = datetime.timedelta(3*365/12)
print (some_date + three_months).isoformat()
# => '2012-06-01'

然后将每个新的一年“正常化”到原来的日期(除非是2月29日)

票数 8
EN

Stack Overflow用户

发布于 2018-05-12 08:44:15

使用Python标准库,即不使用dateutil或其他库,并解决“2月31”问题:

代码语言:javascript
运行
复制
import datetime
import calendar

def add_months(date, months):
    months_count = date.month + months

    # Calculate the year
    year = date.year + int(months_count / 12)

    # Calculate the month
    month = (months_count % 12)
    if month == 0:
        month = 12

    # Calculate the day
    day = date.day
    last_day_of_month = calendar.monthrange(year, month)[1]
    if day > last_day_of_month:
        day = last_day_of_month

    new_date = datetime.date(year, month, day)
    return new_date

测试:

代码语言:javascript
运行
复制
>>>date = datetime.date(2018, 11, 30)

>>>print(date, add_months(date, 3))
(datetime.date(2018, 11, 30), datetime.date(2019, 2, 28))

>>>print(date, add_months(date, 14))
(datetime.date(2018, 12, 31), datetime.date(2020, 2, 29))
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/9594282

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档