Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Create a regular sequence of date-times (POSIXct) using seq()

Tags:

My goal is to create a vector of POSIXct time stamps given a start, an end and a delta (15min, 1hour, 1day). I hoped I could use seq for this, but I have a problem converting between the numeric and POSIXct representation:

now <- Sys.time()
now
# [1] "2012-01-19 10:30:39 CET"
as.POSIXct(as.double(now), origin="1970-01-01", tz="CET")
# [1] "2012-01-19 09:30:39 CET"
as.POSIXct(as.double(now), origin=as.POSIXct("1970-01-01", tz="CET"), tz="CET")
# [1] "2012-01-19 09:30:39 CET"

One hour gets lost during this conversion. What am I doing wrong?

like image 945
Karsten W. Avatar asked Jan 19 '12 10:01

Karsten W.


People also ask

How do I create a date sequence in R?

To create a sequence of dates we can leverage the seq() function. As with numeric vectors, you have to specify at least three of the four arguments ( from , to , by , and length. out ).

What does POSIXct mean in R?

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.

What is POSIXct POSIXt?

class(datetime) ## [1] "POSIXct" "POSIXt" POSIXt is a virtual class which cannot be used directly. “A virtual class 'POSIXt' exists from which both of the classes inherit: it is used to allow operations such as subtraction to mix the two classes.”


2 Answers

There is a seq() method for objects of class "POSIXt" which is the super class of the "POSIXlt" and "POSIXct" classes. As such you don't need to do any conversion.

> now <- Sys.time()
> tseq <- seq(from = now, length.out = 100, by = "mins")
> length(tseq)
[1] 100
> head(tseq)
[1] "2012-01-19 10:52:38 GMT" "2012-01-19 10:53:38 GMT"
[3] "2012-01-19 10:54:38 GMT" "2012-01-19 10:55:38 GMT"
[5] "2012-01-19 10:56:38 GMT" "2012-01-19 10:57:38 GMT"
like image 198
Gavin Simpson Avatar answered Dec 09 '22 23:12

Gavin Simpson


You have to be aware that when converting from POSIXct to numeric, R takes the timezone into account but always starts counting from a GMT origin :

> xgmt <- as.POSIXct('2011-01-01 14:00:00',tz='GMT')
> xest <- as.POSIXct('2011-01-01 14:00:00',tz='EST')
> (as.numeric(xgmt) - as.numeric(xest)) / 3600
[1] -5

As you see, the time in EST is conceived to be five hours earlier than the time in GMT, which is the time difference between both timezones. It's that value that is saved internally.

The as.POSIXCT() function just adds an attribute containing the timezone. It doesn't alter the value, so you get the time presented in GMT time, but with an attribute telling it is EST. This also means that once you go from POSIXct to numeric, you should treat your data as if it's GMT time. (It's a whole lot more complex than that, but it's the general idea). So you have to calculate the offset as follows:

> nest <- as.numeric(xest)
> origin <- as.POSIXct('1970-01-01 00:00:00',tz='EST')
> offset <- as.numeric(origin)
> as.POSIXct(nest-offset,origin=origin)
[1] "2011-01-01 14:00:00 EST"

This works whatever the timezone is in your locale (in my case, that's actually CET). Also note that behaviour of timezone data can differ between systems.

like image 28
Joris Meys Avatar answered Dec 09 '22 22:12

Joris Meys