0

I have this check

if is_time_between(time(6,59,45), time(18,10)):

I want to check if the current time is between the two times I pass in. I think im close.

#from datetime import timezone, datetime, timedelta
from datetime import datetime, time
#import time
import pytz
import dateutil.parser
#from pytz import timezone
    
def is_time_between(begin_time, end_time):
            tz = pytz.timezone('Australia/Sydney')
            check_time = datetime.time(tz)
            if begin_time < end_time:
                return check_time >= begin_time and check_time <= end_time
            else: # crosses midnight
                return check_time >= begin_time or check_time <= end_time

I've gotten multiple errors playing around with imports and froms but the current one is:

descriptor 'time' requires a 'datetime.datetime' object but received a 'Australia/Sydney'
andrewgenard
  • 3
  • 1
  • 3
  • Look at your import. Use `datetime.now(tz)` – Bojan Kogoj Mar 23 '21 at 10:54
  • ah yes I tried that at one point and it led to this error ```'>=' not supported between instances of 'datetime.datetime' and 'datetime.time' ``` question updated* – andrewgenard Mar 23 '21 at 10:56
  • make sure you're not comparing apples with pears - so use either only `datetime.datetime` object or `datetime.time` objects in your comparisons, not a mix. Note that this isn't directly related to pytz or UTC (time zones). – FObersteiner Mar 23 '21 at 10:57
  • @MrFuppes I tried that also but got that error. question updated* I wonder what the right thing to pass in is. – andrewgenard Mar 23 '21 at 11:02
  • side-note: with Python 3.9, you can use `zoneinfo`, which is afaik more convenient than pytz in some aspects - [example](https://stackoverflow.com/questions/1398674/display-the-time-in-a-different-time-zone/63628816#63628816). – FObersteiner Mar 23 '21 at 12:19

2 Answers2

1

Convert your time inputs into dates before you do the comparison. Also pay attention to the make them timezone aware. I've adjusted your method, this works and returns correct results for the current local time in Australia/Sydney:

from datetime import datetime, date, time
import pytz


def is_time_between(begin_time, end_time):
    tz = pytz.timezone('Australia/Sydney')
    now = datetime.now(tz)
    begin_date = datetime.combine(date(now.year, now.month, now.day), begin_time, tzinfo=now.tzinfo)
    end_date = datetime.combine(date(now.year, now.month, now.day), end_time, tzinfo=now.tzinfo)
    if begin_time < end_time:
        return now >= begin_date and now <= end_date
    else:  # crosses midnight
        return now >= begin_date or now <= end_date


print(is_time_between(time(6, 59, 45), time(18, 10)))
print(is_time_between(time(22, 00), time(23, 00)))
print(is_time_between(time(21, 00), time(7, 00)))
print(is_time_between(time(23, 30), time(7, 00)))

Output:

False
True
True
False

(Tested with Python 3.8.0)

yvesonline
  • 4,609
  • 2
  • 21
  • 32
  • oh, yes this is probably a much better way than my solution, quicker and more eloquent. Thanks – andrewgenard Mar 23 '21 at 11:31
  • Yes I'd stick with `datetime` comparisons and not do string comparisons. Feel free to [accept and upvote](https://stackoverflow.com/help/someone-answers) on the answer if this was useful. – yvesonline Mar 23 '21 at 11:33
  • why add a date if you only want to compare *time*? side-note #1: I think setting a pytz tz object like this gives you a wrong UTC offset (should not matter here though). side-note #2: you can just use `now.date()` in the call to `datetime.combine`. – FObersteiner Mar 23 '21 at 12:10
0

I found that if you use this strftime() you can use pytz for the conversion, although you have to make the things you are checking against also string so it can compare, otherwise you are comparing str and datetime.time, and that is an error

def is_time_between(begin_time, end_time, check_time=None):
    # If check time is not given, default to current UTC time
    tz_Aus = pytz.timezone('Australia/Sydney')
    datetime_Aus = datetime.now(tz_Aus)
    check_time = datetime_Aus.strftime("%H:%M:%S")
    if begin_time < end_time:
        return str(check_time) >= str(begin_time) and str(check_time) <= str(end_time)
    else: # crosses midnight
        return str(check_time) >= str(begin_time) or str(check_time) <= str(end_time)
andrewgenard
  • 3
  • 1
  • 3
  • no need for strftime here. just use `datetime_Aus.time()` to only compare time objects, e.g. `check_time = datetime.now(tz_Aus).time()` – FObersteiner Mar 23 '21 at 12:12