add one month to date with lubridate?


I am trying to add one month to a date using lubridate, while making sure the day of the month makes sense when switching (that is moving from a 31 days month to a 30 days month for instance).

I found this solution which works for me:

> ymd('2019-12-01') %m+% months(1)
[1] "2020-01-01"

However I do not undestand what is going on here. First of all, this uses base months() instead of lubridate::months(). Could someone please explain the rationale here? Can I do the same with lubridate only?


1 Like

Just commenting to follow along and get understanding regarding the rationale, but I guess the lubridate only solution would be this, right?

ymd('2019-12-01') %m+% period("1 month")
#[1] "2020-01-01"

great! thanks. but do you know why I need to use the weird %m+% ? what does it mean?


There is no exported function months() in lubridate:

> lubridate::months()
Error: 'months' is not an exported object from 'namespace:lubridate'

Both the base function months() and the lubridate period() function yield the same result:

> months(1)
[1] "1m 0d 0H 0M 0S"

period("1 month")
[1] "1m 0d 0H 0M 0S"

The function %m+% is required if you want to make sure that the additional period falls on a valid day:

> ymd('2020-01-31') %m+% months(1)
[1] "2020-02-29"
> ymd('2020-01-31') + months(1)
[1] NA

> ymd('2020-02-21') + months(1)
[1] "2020-03-21"

I should add regarding the %m+% operator that it is a shorthand for invoking the functionality of add_with_rollback.

The following two examples are exactly the same.

ymd('2019-01-31') %m+% period("1 month")
#> [1] "2019-02-28"

ymd('2019-01-31') %>% add_with_rollback(period("1 month"))
#> [1] "2019-02-28"

Created on 2019-12-16 by the reprex package (v0.3.0)


This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.