2

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]>, ...
WoJ
  • 27,165
  • 48
  • 180
  • 345
  • 2
    You've constructed your range by day, so it's not technically going to include the return of `arrow.now()` unless you just happen to call it exactly at midnight. Options include: change the way the range is constructed, floor/ceiling the query date, or do something with a time delta. – sco1 Sep 06 '17 at 19:23
  • @excaza: ok I understand, thanks. It will look for the exact literal date (at midnight) and `.now()` has the right day/mon/year but not the time. Would you mind turning your comment into an answer so that I can accept it? – WoJ Sep 06 '17 at 19:25
  • I would recommend using epoch time to check the date range. @excaza is totally correct, was about to write the same – harshil9968 Sep 06 '17 at 19:32

2 Answers2

1

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
sco1
  • 12,154
  • 5
  • 26
  • 48
0

This should give you what you want:

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

The key is in the floor() method of the Arrow class: this limits your Arrow object and is required because (as @excaza mentioned) the range gives you day objects at midnight.

I used the utcnow() method instead of the now() method because your arrow.get() usage creates utc dates.

Michael Anckaert
  • 853
  • 8
  • 12