如何使用datetime Python模块计算当前日期六个月的日期?

Rai*_*Son 343 python datetime

我正在使用datetime Python模块.我想计算从当前日期起6个月的日期.有人可以给我一点帮助吗?

我想要从当前日期起6个月生成日期的原因是生成审核日期.如果用户将数据输入系统,则其审核日期为自输入数据之日起6个月.

Mah*_*dra 941

我发现这个解决方案很好.(这使用python-dateutil扩展名)

from datetime import date
from dateutil.relativedelta import relativedelta

six_months = date.today() + relativedelta(months=+6)
Run Code Online (Sandbox Code Playgroud)

这种方法的优点是它可以处理28,30,31天等问题.这在处理业务规则和方案(比如发票生成等)时非常有用.

$ date(2010,12,31)+relativedelta(months=+1)
  datetime.date(2011, 1, 31)

$ date(2010,12,31)+relativedelta(months=+2)
  datetime.date(2011, 2, 28)
Run Code Online (Sandbox Code Playgroud)

  • 这是正确的解决方案.如果OP要求6年而不是6个月,那么批准的答案将会失败.因此,应该记住,答案越有价值,它们就越普遍. (16认同)
  • 喜欢这个答案,但不是'6`之前的`+`多余? (5认同)
  • 是的,+ 6是多余的.它只是作为一个指标. (5认同)
  • +6 是一个指标,它可能是 -6,同样的事情也适用于天和年:) (5认同)
  • 我很好奇:有谁知道为什么默认情况下不包含此内容?默认情况下,Timedelta 似乎与“datetime”一起打包。我实际上认为我可以将“月”传递到 timedelta 中。 (5认同)
  • @dTanMan 因为目前尚不清楚添加一个月至今“(2020, 1, 30)”的结果应该是什么。任何解决该问题的尝试都不是完美的,并且会引发争论。所有这些极端情况和附加功能都由外部“dateutil”包涵盖。 (5认同)
  • @sliders_alpha你需要安装python-dateutil包(pip install python-dateutil) (4认同)
  • 请注意,“ relativedelta”函数还接受“ month”作为参数,该函数基本上替换/设置/修复了通过日期中的month,这与增加多个months完全不同。对于那些想知道该功能是否已被破坏的人们来说,这只是一个警告,因为他们忘记了* month *内额外的* s *。 (2认同)
  • 哇不敢相信我必须向下滚动这么多 (2认同)

var*_*tec 50

那么,这取决于您从当前日期起6个月的意思.

  1. 使用自然月份:

    (day, month, year) = (day, (month+6)%12, year+(month+6)/12)
    
    Run Code Online (Sandbox Code Playgroud)
  2. 使用银行家的定义,6*30:

    date += datetime.timedelta(6*30)
    
    Run Code Online (Sandbox Code Playgroud)

  • 只是一个快速评论:我认为,对于月份,公式将是(月+ 5)%12 + 1 b/c为6月,你的公式给出0而预期结果是12 ...尽管这个小错误,到我的想法是,你的答案是最能回答问题的答案 (10认同)
  • 如果日期为31,而六个月后的月份不能有31天(大多数月份为31天)会怎样? (6认同)
  • 您是否可以投入半年定义(183天)加上26周的定义?它有助于将它们集中在一个地方. (3认同)
  • Downvote因为第一溶液``(日,月,年)=(一天,(月+ 6)%12,年+(月+ 6)/ 12)``可马车,因为它会产生无效的日期,如``( 2015年3月31日,`` - >``(2016年3月31日)`` (3认同)
  • @ruslan_krivoshein,好的,可行。但我认为在最后一个表达式中使用商运算符 // 会更好:`year + (month + 5)//12`。这样就不需要类型转换了,目的也更清晰。 (3认同)
  • 与年份相同:应该为年份+(月+ 5)/ 12 (2认同)
  • 30天不是'银行家定义'.有很多方法可以计算利息支付等天数,而基于30/360 :)的几种方法只是其中的一小部分.http://en.wikipedia.org/wiki/Day_count_convention#30.2F360_methods (2认同)

Arp*_*ini 23

Python 可以使用 datautil 包来实现这一点,请参见下面的示例

不仅限于此,您还可以同时传递日、月和年的组合。

import datetime
from dateutil.relativedelta import relativedelta

# subtract months
proc_dt = datetime.date(2021,8,31)
proc_dt_minus_3_months = proc_dt + relativedelta(months=-3)
print(proc_dt_minus_3_months)

# add months
proc_dt = datetime.date(2021,8,31)
proc_dt_plus_3_months = proc_dt + relativedelta(months=+3)
print(proc_dt_plus_3_months)

# subtract days:
proc_dt = datetime.date(2021,8,31)
proc_dt_minus_3_days = proc_dt + relativedelta(days=-3)
print(proc_dt_minus_3_days)

# add days days:
proc_dt = datetime.date(2021,8,31)
proc_dt_plus_3_days = proc_dt + relativedelta(days=+3)
print(proc_dt_plus_3_days)

# subtract years:
proc_dt = datetime.date(2021,8,31)
proc_dt_minus_3_years = proc_dt + relativedelta(years=-3)
print(proc_dt_minus_3_years)

# add years:
proc_dt = datetime.date(2021,8,31)
proc_dt_plus_3_years = proc_dt + relativedelta(years=+3)
print(proc_dt_plus_3_years)
Run Code Online (Sandbox Code Playgroud)

结果:

2021-05-31

2021-11-30

2021-08-28

2021-09-03

2018-08-31

2024-08-31

  • “Python 有为此构建的库” -> 不,dateutil 不是 python 标准库的一部分。 (2认同)

Luk*_*ina 18

使用Python 3.x,您可以这样做:

from datetime import datetime, timedelta
from dateutil.relativedelta import *

date = datetime.now()
print(date)
# 2018-09-24 13:24:04.007620

date = date + relativedelta(months=+6)
print(date)
# 2019-03-24 13:24:04.007620
Run Code Online (Sandbox Code Playgroud)

但是你需要安装python-dateutil模块:

pip install python-dateutil
Run Code Online (Sandbox Code Playgroud)

  • `pd.DateOffset` 与较新的 `pandas` 中的 `date = date + pd.DateOffset(months=6)` 完全相同,无需安装 `dateutil`,请参阅帮助 (7认同)
  • 我建议“from dateutil.relativedelta importrelativedelta”。使用“import *”并不明确。 (4认同)

小智 17

对于月初计算的开始:

from datetime import timedelta
from dateutil.relativedelta import relativedelta

end_date = start_date + relativedelta(months=delta_period) + timedelta(days=-delta_period)
Run Code Online (Sandbox Code Playgroud)

  • 这不是评论中上面提到的relativedelta解决方案.使用600+ upvotes继续滚动查找解决方案. (15认同)

Joh*_*iss 14

你是什​​么意思'6个月'.是2009-02-13 + 6个月== 2009-08-13还是2009-02-13 + 6*30天?

import mx.DateTime as dt

#6 Months
dt.now()+dt.RelativeDateTime(months=6)
#result is '2009-08-13 16:28:00.84'

#6*30 days
dt.now()+dt.RelativeDateTime(days=30*6)
#result is '2009-08-12 16:30:03.35'
Run Code Online (Sandbox Code Playgroud)

有关更多信息mx.DateTime


小智 14

此解决方案适用于12月,本页面上的大多数答案都没有.在使用模数(%)或整数除法(//)之前,您需要先将月份从基数1(即Jan = 1)转移到基数0(即Jan = 0),否则11月(11)加1个月会给出12 ,当找到余数(12%12)给出0.

(并且不建议"(月%12)+ 1"或10月+ 1 = 12月!)

def AddMonths(d,x):
    newmonth = ((( d.month - 1) + x ) % 12 ) + 1
    newyear  = d.year + ((( d.month - 1) + x ) / 12 ) 
    return datetime.date( newyear, newmonth, d.day)
Run Code Online (Sandbox Code Playgroud)

但是......这并没有像1月31日+一个月那样解决问题.所以我们回到OP - 添加一个月是什么意思?一个解决方案是回溯直到你到达有效的一天,因为大多数人会认为jan的最后一天,加上一个月,等于2月的最后一天.这也将在负数月份工作.证明:

>>> import datetime
>>> AddMonths(datetime.datetime(2010,8,25),1)
datetime.date(2010, 9, 25)
>>> AddMonths(datetime.datetime(2010,8,25),4)
datetime.date(2010, 12, 25)
>>> AddMonths(datetime.datetime(2010,8,25),5)
datetime.date(2011, 1, 25)
>>> AddMonths(datetime.datetime(2010,8,25),13)
datetime.date(2011, 9, 25)
>>> AddMonths(datetime.datetime(2010,8,25),24)
datetime.date(2012, 8, 25)
>>> AddMonths(datetime.datetime(2010,8,25),-1)
datetime.date(2010, 7, 25)
>>> AddMonths(datetime.datetime(2010,8,25),0)
datetime.date(2010, 8, 25)
>>> AddMonths(datetime.datetime(2010,8,25),-12)
datetime.date(2009, 8, 25)
>>> AddMonths(datetime.datetime(2010,8,25),-8)
datetime.date(2009, 12, 25)
>>> AddMonths(datetime.datetime(2010,8,25),-7)
datetime.date(2010, 1, 25)>>> 
Run Code Online (Sandbox Code Playgroud)

  • 修复“1月31日+一个月”问题: days_in_month = calendar.monthrange(newyear, newmonth)[1]; newday = min(d.day, days_in_month); (如果太大,例如 2 月 31 日至 2 月 28 日/29 日,则会降低一天的时间) (3认同)

dan*_*man 13

所以,这里有一个例子dateutil.relativedelta,我发现它有用于迭代过去一年,每次跳过一个月到现在的日期:

>>> import datetime
>>> from dateutil.relativedelta import relativedelta
>>> today = datetime.datetime.today()
>>> month_count = 0
>>> while month_count < 12:
...  day = today - relativedelta(months=month_count)
...  print day
...  month_count += 1
... 
2010-07-07 10:51:45.187968
2010-06-07 10:51:45.187968
2010-05-07 10:51:45.187968
2010-04-07 10:51:45.187968
2010-03-07 10:51:45.187968
2010-02-07 10:51:45.187968
2010-01-07 10:51:45.187968
2009-12-07 10:51:45.187968
2009-11-07 10:51:45.187968
2009-10-07 10:51:45.187968
2009-09-07 10:51:45.187968
2009-08-07 10:51:45.187968
Run Code Online (Sandbox Code Playgroud)

和其他答案一样,你必须在"6个月后"找出你的真正含义.如果你的意思是"未来六个月的今天这个月",那么这样做:

datetime.datetime.now() + relativedelta(months=6)
Run Code Online (Sandbox Code Playgroud)


Mik*_*ies 12

我知道这已经有6个月了,但是如果你要添加一个月,谷歌的答案显示"在python中增加几个月":

import calendar

date = datetime.date.today()    //Or your date

datetime.timedelta(days=calendar.monthrange(date.year,date.month)[1])
Run Code Online (Sandbox Code Playgroud)

这将计算当前月份的天数,并将它们添加到当前日期,使用365/12,如果您的迭代超过日期,则一年中的1/12会导致短/长月问题.


rpa*_*nai 12

这并没有回答具体问题(datetime仅使用),但是,鉴于其他人建议使用不同的模块,这里有一个使用pandas.

import datetime as dt
import pandas as pd

date = dt.date.today() - \
       pd.offsets.DateOffset(months=6)

print(date)

2019-05-04 00:00:00
Run Code Online (Sandbox Code Playgroud)

在闰年按预期工作

date = dt.datetime(2019,8,29) - \
       pd.offsets.DateOffset(months=6)
print(date)

2019-02-28 00:00:00
Run Code Online (Sandbox Code Playgroud)


Akb*_*him 11

使用Python的日期时间没有直接的方法.

查看python-dateutil中的relativedelta类型.它允许您指定以月为单位的时间增量.


kmk*_*lan 11

import datetime
print (datetime.date.today() + datetime.timedelta(6*365/12)).isoformat()
Run Code Online (Sandbox Code Playgroud)

  • 将这个答案视为可接受的答案是令人讨厌的.对于那些寻求准确解决方案的人,在放弃并解决这个答案之前,向下滚动到`dateutil.relativedelta`. (121认同)
  • 答案是不正确的.在这一年,有时366天 (25认同)
  • 啊,是的,如果准确性不重要,添加timedelta是一个简单的解决方案! (12认同)

pi.*_*pi. 9

只需使用timetuple方法提取月份,添加月份并构建新的日期对象.如果有一个已经存在的方法,我不知道.

import datetime

def in_the_future(months=1):
    year, month, day = datetime.date.today().timetuple()[:3]
    new_month = month + months
    return datetime.date(year + (new_month / 12), (new_month % 12) or 12, day)
Run Code Online (Sandbox Code Playgroud)

API有点笨拙,但作为一个例子.显然也不会像2008-01-31 + 1个月那样在角落案件上工作.:)

  • 你的代码出错:`new_month%12`应该是`(new_month%12)或12`.否则,如果您在11月份尝试此操作,则会收到错误消息.:) (3认同)
  • 执行 `new_month / 12` 和 `new_month % 12` 是错误的,因为月份使用基于 1 的索引。您需要转换为基于 0 的索引,执行除法/取模,然后转换回基于 1 的索引。 (2认同)

zgo*_*oda 9

Dateutil包具有此类功能的实现.但请注意,这将是天真的,正如其他人已经指出的那样.


Dav*_*zzi 8

使用Python标准库,即没有dateutil或其他人,并解决'2月31日'问题:

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
Run Code Online (Sandbox Code Playgroud)

测试:

>>>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))
Run Code Online (Sandbox Code Playgroud)

  • 这有一个错误:如果目标月份是 12 月,它将返回比所需日期晚一年的日期。示例:“add_months(datetime.date(2018, 11, 30), 1)”返回“datetime.date(2019, 12, 30)”(年份应该是 2018 年,而不是 2019 年)。因此,最好为此使用专用的、经过良好测试的库!如果您确实只需要使用标准库模块,请参阅[我对类似问题的回答](/sf/answers/2454691081/)。 (2认同)

Die*_*ães 6

一个快速建议是箭头

pip 安装箭头

>>> import arrow

>>> arrow.now().date()
datetime.date(2019, 6, 28)
>>> arrow.now().shift(months=6).date()
datetime.date(2019, 12, 28)
Run Code Online (Sandbox Code Playgroud)


小智 5

我有一个更好的方法来解决“ 2月31日”问题:

def add_months(start_date, months):
    import calendar

    year = start_date.year + (months / 12)
    month = start_date.month + (months % 12)
    day = start_date.day

    if month > 12:
        month = month % 12
        year = year + 1

    days_next = calendar.monthrange(year, month)[1]
    if day > days_next:
        day = days_next

    return start_date.replace(year, month, day)
Run Code Online (Sandbox Code Playgroud)

我认为它也可以使用负数(减去数月),但是我还没有对此进行太多测试。

  • 这个答案的优点是仅使用内置的 Python 库正确解决问题。检查 stackoverflow.com/a/4131114/302264 以获得等效但稍微更简洁的答案。 (2认同)

Dev*_*rre -6

使用 python datetime 模块将六个月的时间增量添加到 datetime.today() 。

\n\n

http://docs.python.org/library/datetime.html

\n\n

你当然要解决Johannes Wei\xc3\x9f提出的问题——6个月是什么意思?

\n

  • timedelta 不支持月份,因此回避了“6 个月中有多少天?”这个问题的可能答案。Eef 的代码将设置一个审核日期,因此我建议您可以考虑使用天(6*30)设置时间增量。如果该时间段代表客户对产品/服务的访问,则可能需要/首选业务定义。 (4认同)