Reputation: 1376
I am trying to add 15 months to an existing date. However the result is not proper end of month which is expected from using %m+% in lubridate.
> as.Date("2018-04-30") %m+% months(15)
[1] "2019-07-30"
Upvotes: 0
Views: 416
Reputation: 263481
You could use the yearmon
class in the zoo package. I think it is better thought out for this purpose than the lubridate
functions appear to be. You would not need to separately calculate the extra days. Notice that additon of months needs to be in years so divide the months by 12. The frac
=1 as argument to as.Date.yearmon
returns the last day of the month:
library(zoo)
as.Date( as.yearmon( as.Date("2018-04-30") ) +15 , frac=1)
[1] "2033-04-30" Wrong!!!
# Divided months by 12
as.Date( as.yearmon( as.Date("2018-04-30") ) +15/12 , frac=1)
[1] "2019-07-31" Success
Upvotes: 0
Reputation: 161110
The %m+%
simply adds the months, at no point is there an assumption that it will maintain the "last day of the month" status. As @duckmayr succinctly stated, it protects against exceeding the end of the month, but I believe it should not be a safe assumption to infer it should push out accordingly.
Alternatives:
rollback(as.Date("2018-04-30") %m+% months(15+1))
# [1] "2019-07-31"
ceiling_date(as.Date("2018-04-30") %m+% months(15), unit="month") - 1
# [1] "2019-07-31"
ceiling_date(as.Date("2018-04-30") %m+% months(15), unit="month") %m+% days(-1)
# [1] "2019-07-31"
And perhaps some further combinations.
Upvotes: 2