5

Suppose I am working with relative delta when it comes to months.

The problem is when I do:

x = relativedelta(months=12)
x.months
> 0

This is a problem when I try to do something like this:

y = relativedelta(months=12) - relativedelta(months=4)

y
> relativedelta(years=+1, months=-4)

y.months
> -4 

I was hoping for a months value of 8 (12 - 4). Anyone know how to best approach this so I can achieve the output I am looking for?

theamateurdataanalyst
  • 2,794
  • 4
  • 38
  • 72
  • `relativedelta(months=12)` is actually `relativedelta(years=+1)` It automatically converts months to years. For example `months=13` would results in `relativedelta(years=+1, months=+1)` – sytech Oct 28 '16 at 13:22

2 Answers2

4

relativedelta(months=12) is actually relativedelta(years=+1) It automatically converts months to years. For example months=13 would result in relativedelta(years=+1, months=+1)

Further, years only change when months go below -11 or above 11. So if the amount of months after the operation is still between -11 and 11, the year will not change.

The solution would be that you need to look at both the rdelta.years and rdelta.months values to get the "net months" you're looking for.

def total_months(rdelta):
    return (rdelta.years * 12) + rdelta.months

You could subclass relativedelta to make this a bit more intuitive for your use.

class reldelta(relativedelta):
    @property
    def total_months(self):
        return (self.years * 12) + self.months

Then

>>> delta = reldelta(years=1) - relativedelta(months=4)
>>> delta
reldelta(years=+1, months=-4)
>>> delta.total_months
8

Of course, this can get messy if you want to try to factor in days to this, because the number of days in a month changes. This is why days are not bounded like months are

>>> relativedelta(days=9999)
relativedelta(days=+9999)
sytech
  • 29,298
  • 3
  • 45
  • 86
0
y = (relativedelta(months=12) - relativedelta(months=4)).months % 12

Essentially, I have used modulo to mitigate the out of bounds values (<0 and >12).

Apoorv Kansal
  • 3,210
  • 6
  • 27
  • 37