I'm looking to build code that represents the definition of months in a piece of Australian legislation - the Interpretations Act (1987).
Please note that I am still a relative novice to Python.
The legal definition
The definition reads as follows:
(1) In any Act, month means a period: (a) starting at the start of any day of one of the calendar months; and. (b) ending: (i) immediately before the start of the corresponding day of the next calendar month; or. (ii) if there is no such day--at the end of the next calendar month.
I've been advised that this definition means that if the start of a month begins on 16/07/2019, for the purposes of a) for example, the relevant month does not conclude until 11:59:59:etc:pm on 15/08/2019 - or functionally, 16/08/2019.
For the purpose of b), then, the "end of a month" is defined at similarly 11:59:59:etc:pm on the relevant final day of the month. So if you have two dates - 31/08/2019 and 30/09/2019 - the relevant month does not conclude until 11:59:59:etc:pm on 30/09/2019 - or functionally, 01/10/2019.
I need to output the difference between two dates in months in order to reflect that the legislation I'm coding asks for a difference between two dates specifically in months.
I'm looking to do this with either datetime or datetime64 objects if possible, to avoid converting between variables unnecessarily.
What I've tried so far.
I've used the below code to find the difference between two dates in months, using relativedelta:
from datetime import datetime
from dateutil import relativedelta
date1 = datetime.strptime('2019-08-15', '%Y-%m-%d')
date2 = datetime.strptime('2020-02-05', '%Y-%m-%d')
r = relativedelta.relativedelta(date2, date1)
r.months + (12*r.years)
print(r)
My expected output for this is 5 months, as there are five complete months and then a fraction of a month that isn't completed by date2. This returns the expected result, and replicates the functionality of a) in the legislation.
However, when I try to replicate b) with the below code:
from datetime import datetime
from dateutil import relativedelta
date1 = datetime.strptime('2019-08-31', '%Y-%m-%d')
date2 = datetime.strptime('2019-11-30', '%Y-%m-%d')
r = relativedelta.relativedelta(date2, date1)
r.months + (12*r.years)
print(r)
This returns the result of 4 months. Because 2019-11-30 is not the end of the relevant calendar month, this is incorrect - I should be getting a result of 3 months for this code, as the month is not completed until 11:59:59:etc.
Expected results
Below are four test cases that I've used to test the results of this code.
from datetime import datetime
from dateutil import relativedelta
date1 = datetime.strptime('2019-08-25', '%Y-%m-%d')
date2 = datetime.strptime('2019-09-10', '%Y-%m-%d')
r = relativedelta.relativedelta(date2, date1)
r.months + (12*r.years)
r.months = 0
from datetime import datetime
from dateutil import relativedelta
date1 = datetime.strptime('2019-08-25', '%Y-%m-%d')
date2 = datetime.strptime('2019-09-25', '%Y-%m-%d')
r = relativedelta.relativedelta(date2, date1)
r.months + (12*r.years)
r.months = 1
from datetime import datetime
from dateutil import relativedelta
date1 = datetime.strptime('2019-08-31', '%Y-%m-%d')
date2 = datetime.strptime('2019-11-30', '%Y-%m-%d')
r = relativedelta.relativedelta(date2, date1)
r.months + (12*r.years)
r.months = 3
from datetime import datetime
from dateutil import relativedelta
date1 = datetime.strptime('2019-08-31', '%Y-%m-%d')
date2 = datetime.strptime('2019-12-01', '%Y-%m-%d')
r = relativedelta.relativedelta(date2, date1)
r.months + (12*r.years)
r.months = 4
EDIT: I've written the inputs for the second two test cases, and after reviewing Alain T.'s response, have revised to the below.
from datetime import datetime
from dateutil import relativedelta
date1 = datetime.strptime('2019-08-01', '%Y-%m-%d')
date2 = datetime.strptime('2019-11-30', '%Y-%m-%d')
r = relativedelta.relativedelta(date2, date1)
r.months + (12*r.years)
r.months = 3
from datetime import datetime
from dateutil import relativedelta
date1 = datetime.strptime('2019-08-01', '%Y-%m-%d')
date2 = datetime.strptime('2019-12-01', '%Y-%m-%d')
r = relativedelta.relativedelta(date2, date1)
r.months + (12*r.years)
r.months = 4
from datetime import datetime
from dateutil import relativedelta
date1 = datetime.strptime('2019-08-31', '%Y-%m-%d')
date2 = datetime.strptime('2019-12-01', '%Y-%m-%d')
r = relativedelta.relativedelta(date2, date1)
r.months + (12*r.years)
r.months = 3