17

Consider the following example:

structure(NA_real_, class = "Date")
## [1] NA
structure(Inf, class = "Date")
## [1] NA
is.na(structure(NA_real_, class = "Date"))
## [1] TRUE
is.na(structure(Inf, class = "Date"))
## [1] FALSE

Both are printing as NA. Is this the expected behavior or is this an error? It is very annoying to see NA for something that won't return TRUE for is.na().

David Arenburg
  • 91,361
  • 17
  • 137
  • 196
stanekam
  • 3,906
  • 2
  • 22
  • 34
  • 1
    So how exactly _should_ `print.Date` display the "end of times". – IRTFM Dec 18 '14 at 19:47
  • My best guess is because `unclass(structure(Inf, class = "Date"))` is not `NA` Inf is not really `NA`, but it is as far as the Date class goes...or something like that – Rich Scriven Dec 18 '14 at 19:55
  • I don't see a method for `is.na.Date`. Not sure if that matters. Very good question! – Rich Scriven Dec 18 '14 at 20:08
  • 4
    @BondedDust What's wrong with printing `Inf`? – Gregor Thomas Dec 18 '14 at 20:08
  • 1
    @Gregor, it is a philosophical question. `Inf` basically saying that time is infinite, while `NA` is basically saying "I don't know and I don't have a way to find out". – David Arenburg Dec 18 '14 at 20:16
  • Don't even need to `unclass` it: `as.numeric(structure(Inf, class = "Date"))` returns `Inf` . – Carl Witthoft Dec 18 '14 at 20:21
  • 3
    But we do know some things, more than we know about typical `NA`s. `Sys.Date() < structure(Inf, class = "Date")` returns `TRUE` very appropriately. – Gregor Thomas Dec 18 '14 at 20:25
  • 3
    I think it is established that R knows that the structure is still Inf. Tracing the source of this behavior: `print.date` -> `format.date` -> `as.POSIXlt` – Vlo Dec 18 '14 at 22:25

1 Answers1

12

This is expected behavior. What is printed is not what the object is. To be printed, the object needs to be converted to character. as.character.Date calls format.Date, which calls format.POSIXlt. The Value section of ?format.POSIXlt (or ?strptime) says:

The format methods and strftime return character vectors representing the time. NA times are returned as NA_character_.

So that's why NA is printed, because printing structure(NA_real_, class = "Date") returns NA_character_. For example:

R> is.na(format(structure(Inf, class = "Date")))
[1] TRUE
R> is.na(format(structure(NaN, class = "Date")))
[1] TRUE

If you somehow encounter these wonky dates in your code, I recommend you test for them using is.finite instead of is.na.

R> is.finite(structure(Inf, class = "Date"))
[1] FALSE
R> is.finite(structure(NaN, class = "Date"))
[1] FALSE
Joshua Ulrich
  • 173,410
  • 32
  • 338
  • 418
  • 2
    Re "NA times are returned as NA_character_" in the doc, I don't think it's relevant here, since it's not a NA time `as.Date(Inf)`prints `NA`but `is.na(as.Date(Inf))` prints `FALSE – moodymudskipper Oct 13 '21 at 09:03
  • I think this goes back to how you define what a "NA time" means. I've seen lots of discussions that `as.Date(Inf)` is *not* a "NA time", but something different instead. I prefer a pragmatic approach, instead of arguing about what it is, or should be. That's why I recommended using `is.finite()` to determine whether or not a Date/POSIXt is valid. – Joshua Ulrich Oct 16 '21 at 13:49