Comment ajouter / heure Soustraire d'un temps de POSIXlt tout en gardant sa classe R?
Question
Je manipulais quelques POSIXlt
objets DateTime. Par exemple, je voudrais ajouter une heure:
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 chose est que je veux new.lt
être un objet POSIXlt
. Je sais que je pourrais utiliser as.POSIXlt
pour le reconvertir en POSIXlt
, mais est-il une façon plus élégante et efficace pour y parvenir?
La solution
Réponse courte: Non
Réponse longue:
objets POSIXct
et POSIXlt
sont deux types de spécifiques de la classe POSIXt
plus générale (et non dans un sens d'héritage objet strictement orienté, mais dans un sens de mise en œuvre orientée quasi-objet). Code passe librement entre ceux-ci. Lorsque vous ajoutez à un objet POSIXlt
, la fonction réelle utilisée est +.POSIXt
, pas un spécialement pour POSIXlt
. Dans cette fonction, l'argument est converti en un POSIXct
puis traité (ajouté à).
En outre, POSIXct
est le nombre de secondes à partir d'une date et une heure. POSIXlt
est une liste de pièces de date (secondes, minutes, heures, jour du mois, mois, année, jour de la semaine, le jour de l'année, info DST) afin d'ajouter à ne directement pas de sens. Conversion à un certain nombre de secondes (POSIXct
) et en ajoutant à cela le fait du sens.
Autres conseils
objets POSIXct
-classés sont en interne une valeur numérique qui permet des calculs numériques. objets POSIXlt
-sont en interne des listes. Malheureusement pour vos désirs, Ops.POSIXt
(qui est ce qu'on appelle lorsque vous utilisez « + ») à POSIXct avec contraint ce code:
if (inherits(e1, "POSIXlt") || is.character(e1))
e1 <- as.POSIXct(e1)
Heureusement, si vous voulez juste une heure et il y a une alternative pratique à l'ajout 3600. Au lieu d'utiliser la structure de la liste et ajouter 1 à l'élément heure:
> my.lt$hour <- my.lt$hour +1
> my.lt
[1] "2010-01-09 23:00:00"
Cette approche est très pratique lorsque vous voulez éviter les changements épineux des questions sur l'heure d'été, au moins si vous voulez ajouter jours pour vous donner le même temps de jour.
Modifier (en ajoutant @ code de sunt démontrant que Ops.POSIXlt
est prudent avec le temps "trop-plein".))
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"
Il ne peut pas être beaucoup plus élégant, mais
seq.POSIXt( from=Sys.time(), by="1 hour", length.out=2 )[2]
à mon humble avis est plus descriptif que
Sys.time()+3600; # 60 minutes * 60 seconds
parce que le code lui-même les documents que vous allez pour un « uence incrémenté « 1 heure », mais il est une question de goût « POSIX » » seq. Fonctionne très bien sur POSIXlt, mais notez qu'il retourne un POSIXct ou l'autre manière. Fonctionne également pour « jours ». Voir l'aide (seq.POSIXt) pour plus de détails sur la façon dont il gère les mois, l'heure d'été, etc.
?POSIXlt
vous dit que:
Toute conversion qui doit passer entre les deux classes de date-heure exige un fuseau horaire. Conversion de « POSIXlt » à « POSIXct » validera fois dans le fuseau horaire sélectionné
Je suppose que 3600 ne pas être un objet POSIXlt
, il y a une conversion automatique.
Je tiendrais avec simple:
new.lt = as.POSIXlt(my.lt + 3600)
class(new.lt)
[1] "POSIXlt" "POSIXt"
Il est pas beaucoup de tracas pour ajouter as.POSIXlt
avant votre opération de temps.