lubridate icon indicating copy to clipboard operation
lubridate copied to clipboard

Add a warning to +months() when results are NA

Open gowerc opened this issue 7 years ago • 5 comments

As explained in the vignette adding and subtracting months can results in either impossible or ambiguous dates. Thus to account for this the default behaviour of lubridate is to set these values to NA, as an example:

> ymd("1990-01-31")  + months(1)
[1] NA

My issue is that currently lubridate does this silently. Thus people who are unaware of this behaviour will have lost data or not have the results they expected.

I propose that if dates are set to NA via this method that a warning should be raised to inform them that this has happened (as odds are they would want to do further processing to account for this situation).

Expectation

> ymd("1990-01-31")  + months(1)
[1] NA
Warning message: NAs produced as date arithmetic resulted in ambiguous dates

gowerc avatar Mar 23 '19 14:03 gowerc

Yeh. This makes sense. It's by far the most frequently asked question here. I wish the defaults were different. Surely you know by now, but just in case use %m+% instead.

vspinu avatar Mar 23 '19 17:03 vspinu

Minimal reprex:

library(lubridate, warn.conflicts = FALSE)

ymd("1990-01-31") + months(1)
#> [1] NA

Created on 2019-11-19 by the reprex package (v0.3.0)

hadley avatar Nov 19 '19 23:11 hadley

The warning message should also be included with years() - but is only an issue for 29-Feb:

> library(lubridate) # v1.7.9
> ymd("2012-02-29") + years(1)
[1] NA

adding with ymd("2012-02-29") %m+% months(12) works, but isn't intuitive when working in the scale of years.

pgstevenson avatar Aug 11 '20 00:08 pgstevenson

I am actually thinking maybe we should change the defaults in the lubridate 2.0.

vspinu avatar Aug 13 '20 11:08 vspinu

In clock, this is an error by default, with multiple options for resolving these invalid dates

library(clock)

x <- date_parse("1990-01-31")

# Error by default
add_months(x, 1)
#> Error: Invalid date found at location 1.
#> ℹ Resolve invalid date issues by specifying the `invalid` argument.

# Next valid date
add_months(x, 1, invalid = "next")
#> [1] "1990-03-01"

# Previous valid date (end of month)
add_months(x, 1, invalid = "previous")
#> [1] "1990-02-28"

# Overflow by 31-28=3 days past the end of February
add_months(x, 1, invalid = "overflow")
#> [1] "1990-03-03"

# Lubridate behavior
add_months(x, 1, invalid = "NA")
#> [1] NA

Created on 2021-05-25 by the reprex package (v1.0.0)

DavisVaughan avatar May 25 '21 13:05 DavisVaughan