I need to check if given date is exactly a month ago from today, for example, if today is 01-Nov-2021 then exactly a month ago will be 01-Oct-2021 (not exactly 30 days.)
I wrote a code and it works fine
today = fields.Date.from_string(fields.Date.today())
if today.month == 1:
one_month_ago = today.replace(year=today.year - 1, month=12)
else:
extra_days = 0
while True:
try:
one_month_ago = today.replace(month=today.month - 1, day=today.day -
extra_days)
break
except ValueError:
extra_days = 1
if one_month_ago == given_date:
# do something
else:
# do something
It handles well mostly all the cases, but mishandles some cases. For example, given date is 31-March-2021 and today date is 30-April-2021 and 31-April-2021 will not come to compare. I need my code to run daily and check something. It also mishandles cases of 29-31 January because 29-31 February will not come to compare.
Any help will matter alot. Thanks.
CodePudding user response:
From the given date, you can find the previous month and year and using these two obtained values, you can find the length of the previous month. The last thing to be done will be to compare the day of the given date with the length of the previous month and accordingly, return the desired date.
Demo:
from datetime import date
from calendar import monthrange
def date_a_month_ago(today):
x = today.month - 1
previous_month = 12 if x == 0 else x
year = today.year - 1 if x == 0 else today.year
last_day_of_previous_month = monthrange(year, previous_month)[1]
day = last_day_of_previous_month if today.day > last_day_of_previous_month else today.day
return date(year, previous_month, day)
# Tests
print(date_a_month_ago(date(2021, 11, 1)))
print(date_a_month_ago(date(2021, 1, 31)))
print(date_a_month_ago(date(2021, 12, 31)))
print(date_a_month_ago(date(2021, 3, 29)))
print(date_a_month_ago(date(2020, 3, 29)))
print(date_a_month_ago(date(2021, 3, 30)))
print(date_a_month_ago(date(2020, 3, 30)))
Output:
2021-10-01
2020-12-31
2021-11-30
2021-02-28
2020-02-29
2021-02-28
2020-02-29
CodePudding user response:
May be like this:
from typing import Tuple
def last_month(year: int, month: int) -> Tuple[int, int]:
y, m = year, month - 1
if m == 0:
y, m = y - 1, 12
return y, m
def one_month_ago(today: datetime) -> datetime:
y, m = last_month(today.year, today.month)
dt = today.replace(year=y, month=m)
for day in range(today.day, 0, -1):
try:
return dt.replace(day=day)
except ValueError:
...
CodePudding user response:
I did this and it's giving me the required output:
from datetime import date
from calendar import monthrange
def is_one_month(given_date, today):
x = today.month - 1
previous_month = 12 if x == 0 else x
year = today.year - 1 if x == 0 else today.year
last_day_of_previous_month = monthrange(year, previous_month)[1]
day = last_day_of_previous_month if today.day > last_day_of_previous_month else today.day
one_month_ago = date(year, previous_month, day)
if today.month == 2:
if given_date.month == today.month-1 and given_date.year == today.year and given_date.day >= 28:
return 'it is one month before'
if today.month == 4 or today.month == 6 or today.month == 9 or today.month == 11:
if given_date.month == today.month-1 and given_date.day == 31:
return 'it is one month before'
if one_month_ago == given_date:
return 'it is one month before'
else:
return 'it is NOT one month before'
print(is_one_month(date(2021, 1, 30), date(2021, 2, 28)))
Output:
it is one month before