0

I have a vector of POSIXct objects:

> dates <- seq(as.POSIXct("2004-01-01", tz="EST"), as.POSIXct("2004-01-02", tz="EST"), as.difftime(6, units="hours"))
> dates
[1] "2004-01-01 00:00:00 EST" "2004-01-01 06:00:00 EST"
[3] "2004-01-01 12:00:00 EST" "2004-01-01 18:00:00 EST"
[5] "2004-01-02 00:00:00 EST"

I create an epoch variable that defines a POSIXct object for the UNIX epoch:

> epoch <- strptime("1970-01-01 00:00:00", "%Y-%m-%d %H:%M:%S", tz="EST")
> class(epoch)
[1] "POSIXct" "POSIXt"  
> epoch
[1] "1970-01-01 EST"

I then loop through the dates vector and print out the value, offset from epoch:

> for (d in dates) { print(as.POSIXct(d, origin=epoch, tz="EST")) }
[1] "2004-01-01 05:00:00 EST"
[1] "2004-01-01 11:00:00 EST"
[1] "2004-01-01 17:00:00 EST"
[1] "2004-01-01 23:00:00 EST"
[1] "2004-01-02 05:00:00 EST"

There seems to be a five-hour offset error between the values in dates and the representation of those same values, relative to epoch.

There is a +5 hr difference between EST and UTC, but I specified the EST time zone for epoch with the tz option. Printing out epoch, there doesn't seem to be the time information, only the date.

Is there a bug with strptime or as.POSIXct, or am I calculating the offset or generating epoch incorrectly?

Alex Reynolds
  • 95,983
  • 54
  • 240
  • 345
  • The (-) five hours is in your epoch, the UNIX epoch is GMT not EST. Why do you even want to do this? `dates` is already a respectable POSIXct / POSIXt object. – mdsumner Jan 06 '12 at 00:09
  • Here, I am defining the epoch as relative to EST, not GMT. Thus, offsets to dates that are EST should not require that correction (unless I misunderstand how `strptime` works). I am exploring this question and I am curious why I am getting the wrong answer: http://stackoverflow.com/questions/8750075/for-loop-style-has-effect-on-class-coercion – Alex Reynolds Jan 06 '12 at 00:14

1 Answers1

1

As mentioned in the answer to For loop style has effect on class coercion?, in the for loop, your dates are converted to numbers. That is the number of seconds since the "standard" epoch. This includes the 5 hour shift between EST and UTC. That is added as an offset to your epoch. See the source of as.POSIXct.numeric.

The following does work because it sets up dates which will be the right number of seconds when converted to numeric.

dates <- seq(as.POSIXct("2004-01-01", tz="UTC"), 
             as.POSIXct("2004-01-02", tz="UTC"), 
             as.difftime(6, units="hours"))
epoch <- strptime("1970-01-01 00:00:00", "%Y-%m-%d %H:%M:%S", tz="EST")

for (d in dates) { print(as.POSIXct(d, origin=epoch, tz="EST")) }

Which gives

[1] "2004-01-01 EST"
[1] "2004-01-01 06:00:00 EST"
[1] "2004-01-01 12:00:00 EST"
[1] "2004-01-01 18:00:00 EST"
[1] "2004-01-02 EST"
Community
  • 1
  • 1
Brian Diggs
  • 57,757
  • 13
  • 166
  • 188
  • `strptime` does return a `POSIXct`, see `?strptime` – Alex Reynolds Jan 06 '12 at 00:25
  • Huh. When I look at `?strptime` it says (in the Details section): "`strptime` converts character vectors to class `POSIXlt`". This is R-2.14.1. That is consistent with the return value I see (via `class(epoch)` or `dput(epoch)`). – Brian Diggs Jan 06 '12 at 00:29
  • I am using R-2.13.0 (2011-04-13) and the description for `strptime` is as follows: "Functions to convert between character representations and objects of classes ‘"POSIXlt"’ and ‘"POSIXct"’ representing calendar dates and times." When I run `class(epoch)` it returns the type I expect (`POSIXct`). – Alex Reynolds Jan 06 '12 at 00:33
  • I didn't realize that the return value had changed. I edited my answer to remove my incorrect comment about that. – Brian Diggs Jan 06 '12 at 05:32