Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to add/subtract time from a POSIXlt time while keeping its class in R?

Tags:

date

time

r

posixct

I am manipulating some POSIXlt DateTime objects. For example I would like to add an hour:

my.lt = as.POSIXlt("2010-01-09 22:00:00")
new.lt = my.lt + 3600
new.lt
# [1] "2010-01-09 23:00:00 EST"
class(new.lt)
# [1] "POSIXct" "POSIXt" 

The thing is I want new.lt to be a POSIXlt object. I know I could use as.POSIXlt to convert it back to POSIXlt, but is there a more elegant and efficient way to achieve this?

like image 484
sunt Avatar asked Jan 13 '12 21:01

sunt


People also ask

How do I subtract hours from time in R?

The hours() method in R is used to take an input integer denoting the number of hours. The lubridate package objects allow direct arithmetic over their various components, therefore the number of hours can be directly subtracted from the lubricate time object. A result is also an object belonging to this class.

What is the difference between POSIXct and Posixt?

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 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.


1 Answers

POSIXct-classed objects are internally a numeric value that allows numeric calculations. POSIXlt-objects are internally lists. Unfortunately for your desires, Ops.POSIXt (which is what is called when you use "+") coerces to POSIXct with this code:

if (inherits(e1, "POSIXlt") || is.character(e1)) 
        e1 <- as.POSIXct(e1)

Fortunately, if you just want to and an hour there is a handy alternative to adding 3600. Instead use the list structure and add 1 to the hour element:

> my.lt$hour <- my.lt$hour +1
> my.lt
[1] "2010-01-09 23:00:00"

This approach is very handy when you want to avoid thorny questions about DST changes, at least if you want adding days to give you the same time-of-day.

Edit (adding @sunt's code demonstrating that Ops.POSIXlt is careful with time "overflow".))

my.lt = as.POSIXlt("2010-01-09 23:05:00") 
my.lt$hour=my.lt$hour+1 
my.lt
# [1] "2010-01-10 00:05:00"
like image 126
IRTFM Avatar answered Sep 19 '22 06:09

IRTFM