-
Notifications
You must be signed in to change notification settings - Fork 210
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
a time_length method #288
a time_length method #288
Conversation
Great! The name is a bit too long. Let's ponder a bit more on it. I will review
|
Overall the code looks good. Please address my comments and squash all commits into one. Could you please add a couple of tests? I have a feeling that it might break with negative intervals because of #285. Does the default method work for the Thanks. |
I will work on it tomorrow. Do you have a specific way to manage tests? |
The default method works on difftime. Regards |
Yes. Simply add a couple of |
OK so I changed the name to So far, I have one failing test, in the specific cases of individuals born a 29 Feb. Please consider the following example: > time_length(interval(ymd('1992-02-29'), ymd('1999-02-28')), "years")
[1] 7
> time_length(interval(ymd('1992-02-29'), ymd('1999-03-01')), "years")
[1] 7.002732 In fact, the 28th Feb 1999, this individual didn't turn 7 yet. The result should be something like 6.99. Computing the period works well: > x <- interval(ymd('1992-02-29'), ymd('1999-02-28'))
> as.period(x)
[1] "6y 11m 30d 0H 0M 0S"
> # NB
> as.period(interval(ymd('1992-02-29'), ymd('1999-03-01')))
[1] "7y 0m 0d 0H 0M 0S" The issue comes from computing next anniversary: > next_anniversary <- int_start(x) %m+% period(7, units = "year")
> next_anniversary
[1] "1999-02-28 UTC" In fact, we should consider that next anniversary is 1999-03-01 (in this specific case). The issue comes from Therefore, should we think about an alternative operator like Note: > age_calc(as.Date('1992-02-29'), as.Date('1999-02-28'), units="years")
[1] 6.997702
> age_calc(as.Date('1992-02-29'), as.Date('1999-03-30'), units="years")
[1] 7.079452 Note 2: I will squash all commits once the pull request will be completely ready. |
Yeah. This is a problem indeed. I think %m++% is actually a good idea. If I wonder if we can use some shortcuts here. Wouldn't it be equivalent to
|
I'm not sure to understand what you mean here. We should also not forget that similar issue exists when dealing with a duration/age in months. |
I was just doing some additional tests, in particular this one: > time_length(interval(ymd('1999-02-28'), ymd('1992-02-29')), "years")
[1] -6.997268
> time_length(interval(ymd('1999-03-01'), ymd('1992-02-29')), "years")
[1] -7.002732 So, with negative intervals, it's exactly the expected result. My first feeling (and I probably need more time to see things more clearly) is about So far, Probably something to explore. |
I meant that maybe we can avoid using %m+% and just check if the year is a leap year. This still leaves out the leap second but that's a minute imprecision.
The main task of %m+/-% is to keep arithmetics of months right. That is, I am still thinking about |
Your shortcut will work.for years, but with months it would be more complex. I don't see right now other use of %m++% except than anniversary computation. Therefore, several options available: 1 Make %m++% an internal function |
Let's take a simpler example:
1993 is not a leap year and it has only 365 days. Adding 365 days to 1992-02-29 lands you into 1993-02-28. This is one way of looking at it. The other way is to consider that next cycle has 366 days. Then you land on 1994-02-28 24:00:00, and the next cycle of 365 days will land you again on 1995-02-28 24:00:00. The interesting part is that next cycle of 365 days will lend you on 1996-02-29 00:00:00 which is exactly right. So it all comes to conventions about the computation of the "start" of the leap year. The second convention is in line with your comment above and I think it's less confusing. Your code adders to the first convention. I have spent quite some time today into bypassing %m+% and I almost got to something, but it's still not working right. You were right, it's far from trivial. |
The issue is also to be consistent with period computation. > as.period(interval(ymd('1992-02-29'), ymd('1993-02-28')))
[1] "11m 30d 0H 0M 0S" We obtain 0 year + 11m 30d so we expect
|
I have updated We still need to decide how to implement |
I have already squashed and merged your old version into 8c08adc. And I have implemented a version that completely bypasses the |
Btw, you are working on a badly broken old version of lubridate. Would be nice if you could add m++ m-- on top of master. |
Alright. I will update my version. Regarding I'm not sure about implementing a Regards |
Let's start first with non-exported version and make sure it works as expected. As I said before, my main concern is that this operator breaks the months arithmetic which is the main point of %m+%.. So I would prefer not to export it unless it's proven useful outside this limited situation. If we have %m++% we will need %m--% to match %m-%. |
See new pull request #292 |
Following #283, a generic
timespan_length
method working with period, duration, difftime and interval objects.I was not sure about the name between
timespan_length
time_length
orspan_length
. The later was not intuitive for me.I didn't change
int_length
yet. Do you want to keep it for backward compatibility (in that case it could be just a wrapper totimespan_length
) or do you want to remove it?Note: currently a S3 method. Should it be changed to a S4 method?