¿Cómo agregar/restar el tiempo de un tiempo de posixlt mientras mantiene su clase en R?

StackOverflow https://stackoverflow.com/questions/8857287

  •  28-10-2019
  •  | 
  •  

Pregunta

Estoy manipulando algunos POSIXlt Objetos de fecha y hora. Por ejemplo, me gustaría agregar una hora:

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" 

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

¿Fue útil?

Solución

Respuesta corta: no

Respuesta larga:

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

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

Otros consejos

POSIXctLos objetos clasificados son internamente un valor numérico que permite cálculos numéricos. POSIXlt-El objects son listas internamente. Desafortunadamente para tus deseos, Ops.POSIXt (que es lo que se llama cuando usa "+") coacciona para posexct con este código:

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

Afortunadamente, si solo desea y una hora hay una alternativa útil para agregar 3600. En su lugar, use la estructura de la lista y agregue 1 al elemento de la hora:

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

Este enfoque es muy útil cuando desea evitar preguntas espinosas sobre los cambios DST, al menos si desea agregar días para darle la misma hora del día.

Editar (agregar el código de @sunt demostrando que Ops.POSIXlt tiene cuidado 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"

Puede que no sea significativamente más elegante, pero

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

En mi humilde opinión es más descriptivo que

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

Porque el código en sí documenta que está buscando un "Posix" "Seq" Uence incrementado "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 Ayuda (SEQ.POSIXT) para obtener detalles sobre cómo maneja meses, ahorros para la luz del día, etc.

?POSIXlt te dice que:

Cualquier conversión que deba ir entre las dos clases de fecha requiere una zona horaria: la conversión de "Posixlt" a "PosIXCT" validará los tiempos en la zona horaria seleccionada.

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

Me quedaría con simple:

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

No es tan difícil agregar as.POSIXlt Antes de su operación de tiempo.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top