3

I'm trying to create this template. Expect to receive September 30, 2022 or October 1, 2022

But I get the next year the same day!

>>> datetime.today()
datetime.datetime(2022, 3, 31, 9, 21, 49, 315991)
>>> rrule.rrule(freq=rrule.MONTHLY, interval=6, dtstart=datetime.today()).after(datetime.today())
datetime.datetime(2023, 3, 31, 9, 18, 3)

EDIT

I want to get a series of dates (every 6 month) and take the nearest:

rrule.rrule(freq=rrule.MONTHLY, interval=6, dtstart=some_date).after(datetime.today())
Sh VavilenT
  • 337
  • 2
  • 9

3 Answers3

4
from datetime import date
from dateutil.relativedelta import relativedelta

six_months = date.today() + relativedelta(months=+6)

The output will be:

>>> date.today()
datetime.date(2022, 3, 31)
>>> six_months
datetime.date(2022, 9, 30)

The advantage of this approach is that it takes care of issues with 28, 30, 31 days etc.

Edit:

relativedelta consumes these parameters:

years, months, weeks, days, hours, minutes, seconds, microseconds

You can also use it with any datetimeobject.

Example:

>>> from datetime import datetime
>>> date_time_str = '18/09/19 01:55:19'
>>> date_time_obj = datetime.strptime(date_time_str, '%d/%m/%y %H:%M:%S')
>>> date_time_obj + relativedelta(years=+7, months=-2, weeks=+16, days=-5, hours=+90, minutes=-100, seconds=+10, microseconds=+20)
datetime.datetime(2026, 11, 5, 18, 15, 29, 20)

Documentation for relativedelta

Ab1gor
  • 398
  • 3
  • 19
  • 1
    Thanks for the answer, If the parameter in after and dtstart will be different? – Sh VavilenT Mar 31 '22 at 10:04
  • @ShVavilenT please check my edited answer. dtstart can be any datetimeobject, and you can tweak parameters of relativedelta to achieve the result. – Ab1gor Mar 31 '22 at 10:11
0

Using rrule like you have and looking at the documentation for it you need to set a number of parameters

from dateutil.rrule import rrule, MONTHLY
from datetime import datetime, timedelta

today = datetime.today() - timedelta(days=1)

# Use rrule to for 6 months from today
six_months = rrule(freq=MONTHLY, interval=6, count=3, dtstart=today)
six_months_list = list(six_months)

# Rrule to date object
for i in six_months_list:
    print(i)

This yields the output

2020-01-01 00:00:00
2020-07-01 00:00:00
2021-01-01 00:00:00

INTERVAL being the months you want because of the MONTHLY frequency COUNT being the number of occurrences that show up in the list ie 3

See documentation for rrule

As mentioned in comments this seems to not work for using datetime.today(). I will need to investigate this further but it does work if using timedelta(days=1) to add or subtract the date.

Aidan Donnelly
  • 369
  • 5
  • 19
  • 2
    if you run this code with today date (not the past date of 2020) you get the result: 2022-03-31 11:51:34 2023-03-31 11:51:34 2024-03-31 11:51:34 – Marcin Cuprjak Mar 31 '22 at 09:51
  • Good spot. This works perfectly if I use yesterday or tomorrow but not today, I wonder what is up with this? – Aidan Donnelly Mar 31 '22 at 09:58
0
rrule.rrule(rrule.DAILY, dtstart=dt_start, interval=183).after(datetime.today())
Sh VavilenT
  • 337
  • 2
  • 9