Bug 14973 - Strange behavior with as.POSIXct & as.POSIXlt
Strange behavior with as.POSIXct & as.POSIXlt
Status: RESOLVED FIXED
Product: R
Classification: Unclassified
Component: Misc
R 2.15.3
x86_64/x64/amd64 (64-bit) Linux
: P5 normal
Assigned To: R-core
Depends on:
Blocks:
  Show dependency treegraph
 
Reported: 2012-07-03 18:30 UTC by Mitch Richling
Modified: 2013-04-09 16:47 UTC (History)
3 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Mitch Richling 2012-07-03 18:30:00 UTC
The "origin" argument seems to not work correctly in as.POSIXct.

R> system('date "+%s"')
1341336072
R> system('date')
Tue Jul  3 12:21:16 CDT 2012
R> as.POSIXlt(1341336072, origin='1970-01-01')
[1] "2012-07-03 12:21:12 CDT"
R> as.POSIXct(1341336072, origin='1970-01-01')
[1] "2012-07-03 18:21:12 CDT"
Comment 1 Simon Urbanek 2012-07-04 00:15:52 UTC
You are not specifying the timezone of the origin and the defaults differ: as.POSIXlt uses GMT whereas as.POSIXct use the time zone you specify with tz which defaults to the current one:

> as.POSIXct(0, origin="1970-01-01")
[1] "1970-01-01 EST"

> as.POSIXct(0, tz="GMT", origin="1970-01-01")
[1] "1970-01-01 GMT"

> as.POSIXct(0, origin=.POSIXct(0))
[1] "1969-12-31 19:00:00 EST"

> as.POSIXlt(0, origin="1970-01-01")
[1] "1969-12-31 19:00:00 EST"

> as.POSIXlt(0, origin="1970-01-01",tz="GMT")
[1] "1970-01-01 GMT"

It's unclear that this is a bug - the documentation only specifies that as.POSIXlt uses GMT. However, the examples in ?as.POSIXct seem to suggest that it is a bug, because of:

     ## suppose we have a time in seconds since 1960-01-01 00:00:00 GMT
     ## (the origin used by SAS)
     z <- 1472562988
     # ways to convert this
     as.POSIXct(z, origin="1960-01-01")                # local

This will be wrong, since the origin is interpreted in the local timezone and not in GMT as the comment suggests. But I'll leave it to those more familiar with the intention there -- especially since any change will affect existing code ...
Comment 2 Garrett See 2013-03-29 04:15:11 UTC
The documentation says that origin should be "a date-time object, or something which can be coerced by ‘as.POSIXct(tz = "GMT")’ to such an object."

To me, that suggests that calling as.POSIXct with origin="1970-01-01" should be the same as with origin=as.POSIXct("1970-01-01", tz="GMT").  However, that is not the case:

R> as.POSIXct(0, origin="1970-01-01")
[1] "1970-01-01 CST"
R> as.POSIXct(0, origin=as.POSIXct("1970-01-01", tz="GMT"))
[1] "1970-01-01 GMT"


I find it surprising that converting a POSIXct object to numeric and back changes the time when origin is character.

R> (x <- Sys.time())
[1] "2013-03-28 21:52:56 CDT"
R> as.POSIXct(as.numeric(x), origin="1970-01-01")
[1] "2013-03-29 03:52:56 CDT"

It also changes when origin is POSIXct
R> as.POSIXct(as.numeric(x), origin=as.POSIXct("1970-01-01", tz="GMT"))
[1] "2013-03-29 02:52:56 GMT"
R> as.POSIXct(as.numeric(x), origin=as.POSIXct("1970-01-01", tz="America/Chicago"))
[1] "2013-03-29 03:52:56 CDT"

However, passing a Date to origin returns the original time, as expected
R> as.POSIXct(as.numeric(x), origin=as.Date("1970-01-01"))
[1] "2013-03-28 21:52:56 CDT"
Comment 3 Simon Urbanek 2013-03-29 16:35:22 UTC
That's fair enough - the "origin" documentation says that it will be coerced using tz="GMT" but as I said it is in fact coerced using as.POSIXct(origin, tz = tz, ..). Now fixed in R-devel.
Comment 4 Bart 2013-04-09 16:47:53 UTC
Following up on errors created by test on cran in r-devel I found that this change adds an empty attribute tzone to the timestamps which was not there before. 

Compare

R version 3.0.0 (2013-04-03) -- "Masked Marvel"
 > l=as.POSIXct(1:10, origin='1970-1-1'); attributes(l);attributes(c(l,l))
$class
[1] "POSIXct" "POSIXt"

$class
[1] "POSIXct" "POSIXt"

To

R Under development (unstable) (2013-04-09 r62531) -- "Unsuffered 
Consequences"
 > l=as.POSIXct(1:10, origin='1970-1-1'); attributes(l);attributes(c(l,l))
$class
[1] "POSIXct" "POSIXt"

$tzone
[1] ""

$class
[1] "POSIXct" "POSIXt"

Of cause I can adjust my error tests to ignore this but I'm not sure adding this empty tzone attribute is informative and if so if it should be dropped when vectors are combined.

What do you think?

Bart

(In reply to comment #3)
> That's fair enough - the "origin" documentation says that it will be coerced
> using tz="GMT" but as I said it is in fact coerced using as.POSIXct(origin, tz
> = tz, ..). Now fixed in R-devel.