pythonpython-3.xarrow-pythonpython-arrow

Why is arrow.now() not in a range containing today's day?


I am testing the ability, in arrow, to check whether a date is in a range of dates:

>>> arrow.get('06/09/2017', 'DD/MM/YYYY') in arrow.Arrow.range('day', arrow.get('06/09/2017', 'DD/MM/YYYY'), arrow.get('06/07/2018', 'DD/MM/YYYY'))
True

>>> arrow.get('06/09/2017', 'DD/MM/YYYY') in arrow.Arrow.range('day', arrow.get('07/09/2017', 'DD/MM/YYYY'), arrow.get('06/07/2018', 'DD/MM/YYYY'))
False

So far so good. I then tried to use .now() in the same construction (today is 6 Sept 2017, the date in the tests above):

>>> arrow.now()
<Arrow [2017-09-06T21:09:02.402790+02:00]>

>>> arrow.now() in arrow.Arrow.range('day', arrow.get('06/09/2017', 'DD/MM/YYYY'), arrow.get('06/07/2018', 'DD/MM/YYYY'))
False

Why is the result False despite .now() being in the range?

>>> arrow.Arrow.range('day', arrow.get('06/09/2017', 'DD/MM/YYYY'), arrow.get('06/07/2018', 'DD/MM/YYYY'))
[<Arrow [2017-09-06T00:00:00+00:00]>, <Arrow [2017-09-07T00:00:00+00:00]>, ...

Solution

  • The way your range is currently constructed is by using a 'day' as your range's frame parameter so, unless your query manages to land exactly at midnight, checking for it the range is going to return False.

    Within Arrow itself, the simplest option is probably to use floor() or ceiling() to normalize your query to how the range is constructed:

    >> myrange = arrow.Arrow.range('day', arrow.get('06/09/2017', 'DD/MM/YYYY'), arrow.get('06/07/2018', 'DD/MM/YYYY'), tz='local')
    >> arrow.now().floor('day') in myrange
    True
    

    Note that I've changed the tz parameter to 'local' so the comparison to arrow.now() is correct. I personally try to do everything with UTC or epoch time rather than keeping track of timezones.

    Alternatively, you can do a simple logical check to see if the current time is after than your range's minimum and before your range's maximum:

    >> myrange = arrow.Arrow.range('day', arrow.get('06/09/2017', 'DD/MM/YYYY'), arrow.get('06/07/2018', 'DD/MM/YYYY'), tz='local')
    >> myrange[0] <= arrow.now() <= myrange[-1]
    True