开发者

Converting date times in POSIXct gives screwy result?

开发者 https://www.devze.com 2023-04-01 05:14 出处:网络
I\'m doing some extracting of data from a database, and running the results through rehsape2.For som开发者_开发百科e reason this is mangling the POSIXct datetime stamps into numeric.No Problem I think

I'm doing some extracting of data from a database, and running the results through rehsape2. For som开发者_开发百科e reason this is mangling the POSIXct datetime stamps into numeric. No Problem I think, you can just turn them back, except I'm an hour out.

Here's a minimal example

foo<-as.POSIXct("2011-04-04 14:18:58")
as.numeric(foo)     #gives 130192318
bar<-as.POSIXct(as.numeric(foo), 
                tz=Sys.timezone(),
                origin=as.POSIXct(
                  strptime("1970-01-01 00:00:00", "%Y-%m-%d %H:%M:%S", tz="UTC")))
as.numeric(bar)     #gives 130192318 identical !
foo     #Gives "2011-04-04 14:18:58 BST"
bar     #Gives "2011-04-04 13:18:58 UTC"

Obviously foo and bar are numerically identical, but R thinks foo needs to be displayed as BST and bar as UTC. How do I get both displayed as BST. This doesn't work either;

as.POSIXct(bar, tz="BST")   #still gives "2011-04-04 13:18:58 UTC"


Here's what's going on. bar is created using as.POSIXct.numeric, which is defined as:

as.POSIXct.numeric
function (x, tz = "", origin, ...) 
{
    if (missing(origin)) 
        stop("'origin' must be supplied")
    as.POSIXct(origin, tz = tz, ...) + x
}
<environment: namespace:base>

You supply an origin that is a POSIXct object. That means the as.POSIXct call in as.POSIXct.numeric dispatches to as.POSIXct.default, which is defined as:

as.POSIXct.default
function (x, tz = "", ...) 
{
    if (inherits(x, "POSIXct")) 
        return(x)
    if (is.character(x) || is.factor(x)) 
        return(as.POSIXct(as.POSIXlt(x, tz, ...), tz, ...))
    if (is.logical(x) && all(is.na(x))) 
        return(.POSIXct(as.numeric(x)))
    stop(gettextf("do not know how to convert '%s' to class \"POSIXct\"", 
        deparse(substitute(x))))
}
<environment: namespace:base>

x is a POSIXct class object (the origin you supplied in your initial call), so it is simply returned and the tz= argument is ignored.


UPDATE:
Here's how you can convert foo back to POSIXct with the appropriate time zone.

(foo <- as.POSIXct("2011-04-04 14:18:58", tz="GB"))
# [1] "2011-04-04 14:18:58 BST"
.POSIXct(as.numeric(foo), tz="GB")
# [1] "2011-04-04 14:18:58 BST"


Here's the kludge I've employed to get round this. By specifying the origin as the current time minus the numeric version of the current time, the timezones don't seem to get screwed up.

foo<-as.POSIXct("2011-04-04 14:18:58")
as.numeric(foo)     #gives 130192318
bar<-as.POSIXct(as.numeric(foo), tz="GB", origin=Sys.time()-as.numeric(Sys.time()))
as.numeric(bar)     #gives 130192318 identical !
foo     #Gives "2011-04-04 14:18:58 BST"
[1] "2011-04-04 14:18:58 BST"
bar     #Gives "2011-04-04 14:18:58 BST"
[1] "2011-04-04 14:18:58 BST
0

精彩评论

暂无评论...
验证码 换一张
取 消