Arrow: span_range and interval return times outside the specified range

Created on 29 Nov 2017  路  9Comments  路  Source: arrow-py/arrow

The implementation of span_range (and also interval()) is surprising to me, and is not what I would expect from a range function.

            >>> start = datetime(2013, 5, 5, 12, 30)
            >>> end = datetime(2013, 5, 5, 17, 15)
            >>> for r in arrow.Arrow.span_range('hour', start, end):
            ...     print(r)
            ...
            (<Arrow [2013-05-05T12:00:00+00:00]>, <Arrow [2013-05-05T12:59:59.999999+00:00]>)
            (<Arrow [2013-05-05T13:00:00+00:00]>, <Arrow [2013-05-05T13:59:59.999999+00:00]>)
            (<Arrow [2013-05-05T14:00:00+00:00]>, <Arrow [2013-05-05T14:59:59.999999+00:00]>)
            (<Arrow [2013-05-05T15:00:00+00:00]>, <Arrow [2013-05-05T15:59:59.999999+00:00]>)
            (<Arrow [2013-05-05T16:00:00+00:00]>, <Arrow [2013-05-05T16:59:59.999999+00:00]>)
            (<Arrow [2013-05-05T17:00:00+00:00]>, <Arrow [2013-05-05T17:59:59.999999+00:00]>)

I think the return value should be:

            (<Arrow [2013-05-05T12:30:00+00:00]>, <Arrow [2013-05-05T13:29:59.999999+00:00]>)
            (<Arrow [2013-05-05T13:30:00+00:00]>, <Arrow [2013-05-05T14:29:59.999999+00:00]>)
            (<Arrow [2013-05-05T14:30:00+00:00]>, <Arrow [2013-05-05T15:29:59.999999+00:00]>)
            (<Arrow [2013-05-05T15:30:00+00:00]>, <Arrow [2013-05-05T16:29:59.999999+00:00]>)
            (<Arrow [2013-05-05T16:30:00+00:00]>, <Arrow [2013-05-05T17:14:59.999999+00:00]>)

The first span should start at the specified start, and the final span should truncate so as not to extend beyond end.

I know "span" means something specific (arrow.utcnow().span('day')) and span_range() makes sense considering that definition, but this function still seems surprising and broken. Perhaps however I'm unaware of a use case for the existing span_range(), and I actually want to write a different function like split_range()?

At the very least, my use case is along the lines of:

start_date = arrow.get('2011-02-01')
end_date = arrow.get('2017-11-24')
for start, end in arrow.Arrow.interval('day', start_date, end_date , max_days_to_sync):
    service.syncdata(start, end)

And this breaks when I inadvertently sync data outside the dates I asked for.

I'm happy to submit a pull request or discuss further.

bug good first issue

All 9 comments

Seems like a bug, line 260ish in range definition is where it is at, needs a truncate if the end date is reached. span_range uses range, interval uses span_range

https://github.com/crsmithdev/arrow/pull/466 might fix the issue for you regarding interval, although it won't fix span_range.

ref #466 #533

Both the above PR's tried to fix the problems in interval and span_range but due to failing builds and staleness are no longer viable. We favor implementing an exact kwarg in both methods to allow either behavior in @dwrpayne's post.

I will try working on this

I can give this a try as well!

Hi @egannon you might want to look at the old PR for this (#731), the fix worked bar a few edge cases.

edit: actually #817 was the revamped PR by Jad.

Yeah take a look at the existing PRs for sure. It seems like there were some existing edge cases that came up during our manual testing, so the PR was 90% there, but couldn't get merged in the end.

Hi! Emma and I are working on this issue together. We were able to replicate that bug after integrating Arrow's most up-to-date code with the code additions from #817 and seem to have found the fix to that specific sample test that was causing a bug (where floor==end). We're new to open source contributions - what would be the best way to continue tackling this issue? Should we continue adding tests for the exact keyword in span_range, interval, and span?

Any guidance would be appreciated! Thank you

Hi @svanita00 the best way to proceed would be to open a PR with your changes. That way we can see what changes you've made and point you in the right direction.

Was this page helpful?
0 / 5 - 0 ratings