horaceT
horaceT

Reputation: 661

strange behavior of POSIX date-times

This behavior of POSIX objects baffles me. I make two POSIX date-time vectors, one POSIXct and other POSIXlt, that have the same dates and times. They are identical by == but not by %in% as seen in the following.

d.ch = c("2016-09-26 0:00:00", "2016-09-26 1:00:00", "2016-09-26 2:00:00", "2016-09-26 3:00:00", "2016-09-26 4:00:00")
d1 = strptime(d.ch, format="%Y-%m-%d %H:%M:%S") # POSIXlt
d3 = seq(from=ISOdatetime(2016,9,26,0,0,0), 
     length.out=5, by="hour") # POSIXct
d1 == d3
[1] TRUE TRUE TRUE TRUE TRUE

but

d1 %in% d3
[1] FALSE FALSE FALSE FALSE FALSE

Why?

Upvotes: 1

Views: 169

Answers (2)

Joshua Ulrich
Joshua Ulrich

Reputation: 176718

Both POSIXct and POSIXlt inherit from the virtual POSIXt class. That is what allows binary operators like ==, +, -, etc to work when one object is POSIXct and the other is POSIXlt. Those binary functions look at the class of their arguments.

%in% calls match, which does a lookup of a value from a table. There's no S3 method dispatch to take advantage of the POSIXt virtual class, so you get a vector of FALSE.

Upvotes: 2

Dirk is no longer here
Dirk is no longer here

Reputation: 368539

It all works if you just convert the strptime() result to POSIXct.

Or if you use anytime() which creates POSIXct by default too:

R> library(anytime)
R> d1 <- anytime(c("2016-09-26 00:00:00", "2016-09-26 01:00:00", 
+  "2016-09-26 02:00:00", "2016-09-26 03:00:00", "2016-09-26 04:00:00"))
R> d1
[1] "2016-09-26 00:00:00 CDT" "2016-09-26 01:00:00 CDT" "2016-09-26 02:00:00 CDT" 
[4] "2016-09-26 03:00:00 CDT" "2016-09-26 04:00:00 CDT"
R> d3 <- seq(from=ISOdatetime(2016,9,26,0,0,0), length.out=5, by="hour") # POSIXct
R> d3
[1] "2016-09-26 00:00:00 CDT" "2016-09-26 01:00:00 CDT" "2016-09-26 02:00:00 CDT" 
[4] "2016-09-26 03:00:00 CDT" "2016-09-26 04:00:00 CDT"
R> d1 == d3
[1] TRUE TRUE TRUE TRUE TRUE
R> d1 %in% d3
[1] TRUE TRUE TRUE TRUE TRUE
R> 

Because anytime() iterates over a set pre-coded formats, I had to add a zero to your hour format to make it like a regular ISOtime format.

(Oh, and CDT happens to be my timezone.)

Upvotes: 2

Related Questions