Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Converting date times in POSIXct gives screwy result?

Tags:

time

r

I'm doing some extracting of data from a database, and running the results through rehsape2. For some 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"
like image 606
PaulHurleyuk Avatar asked Aug 31 '11 13:08

PaulHurleyuk


People also ask

What is the difference between POSIXlt and POSIXct?

There are two POSIX date/time classes, which differ in the way that the values are stored internally. The POSIXct class stores date/time values as the number of seconds since January 1, 1970, while the POSIXlt class stores them as a list with elements for second, minute, hour, day, month, and year, among others.

What does as POSIXct do in R?

as. POSIXct stores both a date and time with an associated time zone. The default time zone selected, is the time zone that your computer is set to which is most often your local time zone. POSIXct stores date and time in seconds with the number of seconds beginning at 1 January 1970.

How do I convert to time in R?

To convert characters to time objects in R, use the strptime() function. To convert time objects to characters in R, use the strftime() function.

What does POSIXct stand for?

The basic POSIX measure of time, calendar time, is the number of seconds since the beginning of 1970, in the UTC timezone (GMT as described by the French).


1 Answers

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"
like image 152
Joshua Ulrich Avatar answered Nov 15 '22 15:11

Joshua Ulrich