Come aggiungere/sottrarre il tempo da un tempo posixlt mantenendo la sua classe in r?

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

  •  28-10-2019
  •  | 
  •  

Domanda

Sto manipolando un po ' POSIXlt Oggetti datetime. Ad esempio, vorrei aggiungere un'ora:

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" 

Il fatto è che voglio new.lt essere un POSIXlt oggetto. So che potrei usare as.POSIXlt per convertirlo a POSIXlt, ma esiste un modo più elegante ed efficiente per raggiungere questo obiettivo?

È stato utile?

Soluzione

Risposta breve: no

Risposta lunga:

POSIXct e POSIXlt Gli oggetti sono due tipi specifici del più generale POSIXt Classe (non in un senso ereditario strettamente orientato agli oggetti, ma in un senso di implementazione orientato quasi agli oggetti). Codice cambia liberamente tra questi. Quando aggiungi a un POSIXlt oggetto, la funzione effettiva utilizzata è +.POSIXt, non uno specifico per POSIXlt. All'interno di questa funzione, l'argomento viene convertito in a POSIXct e poi affrontato (aggiunto a).

Inoltre, POSIXct è il numero di secondi da una data e ora specifiche. POSIXlt è un elenco di parti della data (secondi, minuti, ore, giorno del mese, mese, anno, giorno della settimana, giorno dell'anno, informazioni DST), quindi aggiungerlo direttamente non ha alcun senso. Convertendolo in diversi secondi (POSIXct) e aggiungere a ciò ha senso.

Altri suggerimenti

POSIXct-Il gli oggetti di classe sono internamente un valore numerico che consente calcoli numerici. POSIXlt-Objects sono elenchi interni. Purtroppo per i tuoi desideri, Ops.POSIXt (che è quello che viene chiamato quando usi "+") costringe a posixCT con questo codice:

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

Fortunatamente, se lo desideri e un'ora c'è una pratica alternativa all'aggiunta di 3600. Usa invece la struttura dell'elenco e aggiungi 1 all'elemento ora:

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

Questo approccio è molto utile quando vuoi evitare spinose domande sui cambiamenti di DST, almeno se vuoi aggiungere giorni per darti lo stesso orario.

Modifica (aggiungendo il codice di @sunt che lo dimostra Ops.POSIXlt è attento con il tempo "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"

Potrebbe non essere significativamente più elegante, ma

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

IMHO è più descrittivo di

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

Perché il codice stesso documenta che stai andando per un "seq" uence ha incrementato "di 1 ora", ma è una questione di gusti. Funziona bene su Posixlt, ma nota che restituisce un posixct in entrambi i casi. Funziona anche per "giorni". Vedere Aiuto (seq.PoPixt) per i dettagli su come gestisce mesi, risparmio diurno, ecc.

?POSIXlt te lo dice:

Qualsiasi conversione che deve andare tra le due classi di data-tempo richiede un fuso orario: la conversione da "Posixlt" a "PosixCt" convaliderà i tempi nel fuso orario selezionato.

Quindi immagino che 3600 non sia un POSIXlt Oggetto, c'è una conversione automatica.

Rimanerei con semplice:

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

Non è così tanto da aggiungere as.POSIXlt Prima dell'operazione di tempo.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top