tidyverse / lubridate

Make working with dates in R just that little bit easier
https://lubridate.tidyverse.org
GNU General Public License v3.0
731 stars 207 forks source link

floor_date(Inf) is NA #1114

Closed torfason closed 1 year ago

torfason commented 1 year ago

The floor_date() function returns NA for infinite times (positive or negative). This seems wrong.

An Inf time is a time after all others, and flooring or rounding that to the nearest day, hour, minute or second, should also result in a time after all others, rather than a missing value. This can be quite useful, and other issues have discussed how this is a legitimate use (see e.g. #1020, but note that this is not a duplicate of that issue, the value of floor_date() does not just print as NA it reallly is NA).

This applies to -Inf and to ceiling_date()as well.

But notably not to round_date()!

See reprex below.

# A double for comparison
x <- as.double(Inf)
x |> floor()
#> [1] Inf
x |> ceiling()
#> [1] Inf
x |> round()
#> [1] Inf
x |> round(digits=2)
#> [1] Inf

# Load, set 
library(lubridate, warn.conflicts = FALSE)
t <- as.POSIXct(Inf)

# Various examples
t
#> [1] "Inf"
t |> as_date()
#> [1] "Inf"
t |> floor_date()
#> [1] NA
t |> floor_date(unit="seconds")
#> [1] NA
t |> floor_date(unit="minutes")
#> [1] NA
t |> floor_date(unit="hours")
#> [1] NA
t |> floor_date(unit="days")
#> [1] NA

# Applies to ceiling_date()
t |> ceiling_date()
#> [1] NA

# But not to round_date()
t |> round_date()
#> [1] "Inf"

# It really is an NA
t |> floor_date() |> is.na()
#> [1] TRUE
vspinu commented 1 year ago

This is a valid point. Needs to be fixed.

vspinu commented 1 year ago

A complication is that even internal round.POSIXt is not doing it correctly

> tinf <- .POSIXct(c(Inf, -Inf))
> round.POSIXt(tinf)
[1] "Inf"  "-Inf"
> round.POSIXt(tinf, "day")
[1] NA NA
vspinu commented 1 year ago

You would need to install timechange from github for now.

torfason commented 1 year ago

I can confirm that installing the GitHub version of timechange fixes this for me.

Thanks, that was fast :-)