# [R] diff, POSIXct, POSIXlt, POSIXt

Spencer Graves spencer.graves at pdf.com
Sun Jul 23 20:57:48 CEST 2006

```Hi, Gabor:

For my 0.02 euros, I vote to make length(POSIXlt) = length of the
series, NOT the length of the list = 9 always.  I've stubbed my toe on
that one many times.  I always fix it by converting first to POSIXct.

The key question is what would users naively expect to get from
length(a_time_series)?  I think most people not familiar with the
POSIXlt format would expect the number of observations.  After
struggling for a while with code that did not perform as expected, I
finally traced one such problem to the fact that length(a_time_series)=
9 if class(a_time_series) = "POSIXlt", independent of the number of
observations.

How much code would break if this was changed?  Each use of
length(POSIXlt_object) would have to be replaced by something like
length(as.list(POSIXlt_object)).  However, since length(POSIXlt_object)
is always 9, I doubt if length(POSIXlt_object) occurs very often.

Currently to get the number of observations in a POSIXlt_object, you
might find constructs like length(POSIXlt_object[[1]]).  Or you will
find people converting the POSIXlt to POSIXct and then computing the
length.  In either case, changing length(POSIXlt_object) to the number
of observations would not break any of this code.

Thanks for raising this question.
Spencer Graves

Gabor Grothendieck wrote:
> Moving this to r-devel.
>
> Looking at the diff.POSIXt code we see the problem is that it takes the
> length of the input using length which is wrong since in the case
> of POSIXlt the length is always 9 (or maybe length should be
> defined differently for POSIXlt?).  Try this which gives the same
> problem:
>
>    dts[-1] - dts[-length(dts)]
>
> We get a more sensible answer if length is calculated correctly:
>
>   dts[-1] - dts[-length(dts[[1]])]
>
>
> On 7/23/06, Patrick Giraudoux <patrick.giraudoux at univ-fcomte.fr> wrote:
>>> Try converting to POSIXct:
>> That's what I did finally (see the previous e-mail).
>>
>> dts<-c("15/4/2003","15/7/2003","15/10/2003","15/04/2004","15/07/2004","15/10/2004","15/4/2005","15/07/2005","15/10/2005","15/4/2006")
>>
>> dts <- as.POSIXct(strptime(dts, "%d/%m/%Y"))
>> diff(dts)
>>
>> Time differences of  91,  92, 183,  91,  92, 182,  91,  92, 182 days
>>
>>> What is the problem you are trying to solve?
>> Actually, I don't understand why using diff() and POSIXct provides the
>> expected result and not using POSIXlt. Both POSIXct and POSIXlt are of
>> class POSIXt. The doc of diff() stresses that <'diff' is a generic
>> function with a default method and ones for classes '"ts"', '"POSIXt"'
>> and '"Date"'>. It does not mention differences between POSIXct and POSIXlt.
>>
>> Moreover, using diff() with POSIXlt has provided (wrong) numbers... and
>> not an error. This may be difficult to detect sometimes along programme
>> lines. Must one keep in mind that diff() is reliably applicable only on
>> POSIXct? In this case, should not it bve mentionned in the documentation?
>>
>> All the best,
>>
>> Patrick
>>
>>
>>
>>
>>
>>
>>
>> jim holtman a écrit :
>>> Try converting to POSIXct:
>>>
>>>> str(dts)
>>> 'POSIXlt', format: chr [1:10] "2003-04-15" "2003-07-15" "2003-10-15"
>>> "2004-04-15" "2004-07-15" "2004-10-15" "2005-04-15" ...
>>>> dts
>>>  [1] "2003-04-15" "2003-07-15" "2003-10-15" "2004-04-15" "2004-07-15"
>>> "2004-10-15" "2005-04-15" "2005-07-15"
>>>  [9] "2005-10-15" "2006-04-15"
>>>> dts <- as.POSIXct(dts)
>>>> dts
>>>  [1] "2003-04-15 EDT" "2003-07-15 EDT" "2003-10-15 EDT" "2004-04-15
>>> EDT" "2004-07-15 EDT" "2004-10-15 EDT"
>>>  [7] "2005-04-15 EDT" "2005-07-15 EDT" "2005-10-15 EDT" "2006-04-15 EDT"
>>>> diff(dts)
>>> Time differences of  91,  92, 183,  91,  92, 182,  91,  92, 182 days
>>>
>>>
>>> On 7/23/06, *Patrick Giraudoux* <patrick.giraudoux at univ-fcomte.fr
>>> <mailto:patrick.giraudoux at univ-fcomte.fr>> wrote:
>>>
>>>     Dear Listers,
>>>
>>>     I have encountered a strange problem using diff() and POSIXt:
>>>
>>>     dts<-c("15/4/2003","15/7/2003","15/10/2003","15/04/2004","15/07/2004","15/10/2004","15/4/2005","15/07/2005","15/10/2005","15/4/2006")
>>>
>>>     dts <- strptime(dts, "%d/%m/%Y")
>>>     class(dts)
>>>
>>>     [1] "POSIXt"  "POSIXlt"
>>>
>>>     diff(dts)
>>>
>>>     Time differences of  7862400,  7948800, 15811200,  7862400,  7948800,
>>>     15724800,  7862400,  7948800,        0 secs
>>>
>>>     In this case the result is not the one expected: expressed in seconds
>>>     and not in days, and the difference between the two last dates is
>>>     not 0.
>>>
>>>     Now, if one use a vector of 9 dates only (whatever the date removed),
>>>     things come well:
>>>
>>>     diff(dts[-1])
>>>
>>>     Time differences of  92, 183,  91,  92, 182,  91,  92, 182 days
>>>
>>>     Also if one contrains dts to POSIXct
>>>
>>>     dts<-c("15/4/2003","15/7/2003","15/10/2003","15/04/2004","15/07/2004","15/10/2004","15/4/2005","15/07/2005","15/10/2005","15/4/2006")
>>>
>>>     dts <- as.POSIXct(strptime(dts, "%d/%m/%Y"))
>>>     diff(dts)
>>>
>>>     Time differences of  91,  92, 183,  91,  92, 182,  91,  92, 182 days
>>>
>>>     Any rational in that?
>>>
>>>     Patrick
>>>
>>>     ______________________________________________
>>>     R-help at stat.math.ethz.ch <mailto:R-help at stat.math.ethz.ch> mailing
>>>     list
>>>     https://stat.ethz.ch/mailman/listinfo/r-help
>>>     http://www.R-project.org/posting-guide.html
>>>     and provide commented, minimal, self-contained, reproducible code.
>>>
>>>
>>>
>>>
>>> --
>>> Jim Holtman
>>> Cincinnati, OH
>>> +1 513 646 9390
>>>
>>> What is the problem you are trying to solve?
>>        [[alternative HTML version deleted]]
>>
>>
>>
>> ______________________________________________
>> R-help at stat.math.ethz.ch mailing list
>> https://stat.ethz.ch/mailman/listinfo/r-help
>> and provide commented, minimal, self-contained, reproducible code.
>>
>>
>>
>
> ______________________________________________
> R-help at stat.math.ethz.ch mailing list
> https://stat.ethz.ch/mailman/listinfo/r-help