2012-01-13 12 views
13

Estoy manipulando algunos objetos DateTime POSIXlt. Por ejemplo, me gustaría añadir una hora:¿Cómo agregar/restar tiempo de un tiempo POSIXlt mientras mantiene su clase en R?

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" 

Lo que pasa es que quiero new.lt a ser un objeto POSIXlt. Sé que podría usar as.POSIXlt para convertirlo de nuevo a POSIXlt, pero ¿hay una manera más elegante y eficiente de lograr esto?

Respuesta

12

Respuesta corta: No

Respuesta larga:

POSIXct y POSIXlt objetos son dos tipos específicos de la POSIXt clase más general (no en un sentido de herencia estrictamente orientado a objetos, pero en un cuasi-orientado a objetos sentido de implementación). El código cambia libremente entre estos. Cuando agrega a un objeto POSIXlt, la función real utilizada es +.POSIXt, no específicamente para POSIXlt. Dentro de esta función, el argumento se convierte en POSIXct y luego se trata (agregado a).

Además, POSIXct es el número de segundos de una fecha y hora específicas. POSIXlt es una lista de partes de la fecha (segundos, minutos, horas, día del mes, mes, año, día de la semana, día del año, información de horario de verano) por lo que no tiene sentido agregar eso directamente. Convertirlo a una cantidad de segundos (POSIXct) y agregarlo tiene sentido.

+1

Brian, entiendo que POSIXct es numérico y POSIXlt es una lista. Sin embargo, uno no siempre puede codificar libremente entre estos dos. Un ejemplo es cuando convierte zonas horarias, tiene que usar el tiempo calendario en lugar de la hora local (http://blog.revolutionanalytics.com/2009/06/converting-time-zones.html). La otra cosa es que es mucho más rápido para convertir entre hora local y caracteres que para convertir entre el tiempo del calendario y los caracteres. – sunt

5

?POSIXlt le dice que:

Cualquier conversión que tiene que ir entre las dos clases de fecha y hora requiere una zona horaria: conversión de "POSIXlt" a "POSIXct" validará veces en la zona horaria seleccionada.

Así que supongo que 3600 no es un objeto POSIXlt, hay una conversión automática.

me gustaría seguir con sencillo:

new.lt = as.POSIXlt(my.lt + 3600) 
class(new.lt) 
[1] "POSIXlt" "POSIXt" 

No es que gran parte de una molestia para agregar as.POSIXlt antes de la operación de tiempo.

14

POSIXct -los objetos clasificados son internamente un valor numérico que permite cálculos numéricos. POSIXlt -objetos son listas internas. Por desgracia para sus deseos, Ops.POSIXt (que es lo que se llama cuando se utiliza "+") coacciona a POSIXct con este código:

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

Afortunadamente, si lo que desea es ya una hora no es una alternativa útil a la adición 3600. en lugar de utilizar la estructura de la lista y se añade 1 al elemento horas:

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

Este enfoque es muy útil cuando se quiere evitar preguntas espinosas sobre los cambios de horario de verano, al menos si se desea añadir días para darle la misma hora del día.

Editar (agregando el código de @ sunt demostrando que Ops.POSIXlt es cuidadoso con el tiempo "desbordamiento".))

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" 
+0

En realidad, R es lo suficientemente inteligente como para pasar al día siguiente si es necesario: > my.lt = as.POSIXlt ("2010-01-09 23:05:00") > my.lt $ hour = my. lt $ hora + 1 > my.lt [1] "2010-01-10 00:05:00" Perdón, parece que no puedo darle un buen formato en los comentarios ... – sunt

+0

Correcto, de hecho eso fue mi punto. Si agrega 25 horas, obtendrá el día siguiente y la hora adicional. Pero si agrega 100 días y como resultado cruza un límite de horario de verano, no pierda ni agregue una hora. –

7

Puede que no sea significativamente más elegante, pero

seq.POSIXt(from=Sys.time(), by="1 hour", length.out=2)[2] 

mi humilde opinión es más descriptivo que

Sys.time()+3600; # 60 minutes * 60 seconds 

debido a que el código en sí documentos que vas para un " POSIX "seq" uence incrementó "por 1 hora", pero es una cuestión de gusto. Funciona bien en POSIXlt, pero tenga en cuenta que devuelve un POSIXct de cualquier manera. También funciona para "días". Consulte la ayuda (seq.POSIXt) para obtener detalles sobre cómo maneja meses, horario de verano, etc.

Cuestiones relacionadas