How to Determine If Current Time Is Within a Specified Range Using Python'S Datetime Module

How do I determine if current time is within a specified range using Python's datetime module?

My original answer focused very specifically on the question as posed and didn't accommodate time ranges that span midnight. As this is still the accepted answer 6 years later, I've incorporated @rouble's answer below that expanded on mine to support midnight.

from datetime import datetime, time

def is_time_between(begin_time, end_time, check_time=None):
# If check time is not given, default to current UTC time
check_time = check_time or datetime.utcnow().time()
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

# Original test case from OP
is_time_between(time(10,30), time(16,30))

# Test case when range crosses midnight
is_time_between(time(22,0), time(4,00))

I still stick to my original comment below that most applications of this logic would probably be better suited with datetime objects where crossing midnight is reflected as a date change anyway.

How to check if the current time is in range in python?

The Python solution is going to be much, much shorter.

def time_in_range(start, end, x):
"""Return true if x is in the range [start, end]"""
if start <= end:
return start <= x <= end
else:
return start <= x or x <= end

Use the datetime.time class for start, end, and x.

>>> import datetime
>>> start = datetime.time(23, 0, 0)
>>> end = datetime.time(1, 0, 0)
>>> time_in_range(start, end, datetime.time(23, 30, 0))
True
>>> time_in_range(start, end, datetime.time(12, 30, 0))
False

Python and check if current datetime is in specific range

Neatest way is to use the amount of minutes elapsed in a week:

def mins_in_week(day, hour, minute):
return day * 24 * 60 + hour * 60 + minute

if (mins_in_week(1, 16, 30) <
mins_in_week(TimeNow.weekday(), TimeNow.hour, TimeNow.minute) <
mins_in_week(3, 11, 45)):
....

How to check if current time is between a certain time period?

Access the hour field using current_time.hour which returns anint which implies that it should not be compared with str.

You can do therefore:

import datetime
current_time = datetime.datetime.now().time()

if 22<= current_time.hour <=23:
print ("current time is between 10:00pm to 11:00pm")
else:
print ("current time is NOT between 10:00pm to 11:00pm")

Check if time is between tonight and tomorrow morning

How could the hour be simultaneously >= 23 and <= 8?

Try replacing and with or:

if now_time >= time(23,00) or now_time <= time(8,00):
print "night"

How to get all times within a time range

Using the date time module might be useful. Here's my idea for your problem if you were to use military time:

import datetime

start = datetime.time(10,0) # 10:00
end = datetime.time(10,5) # 10:05
TIME_FORMAT = "%H:%M" # Format for hours and minutes
times = [] # List of times
while start <= end:
times.append(start)
if start.minute == 59: # Changes the hour at the top of the hour and set the minutes back to 0
start = start.replace(minute=0) # have to use the replace method for changing the object
start = start.replace(hour=start.hour + 1)
else:
start = start.replace(minute=start.minute + 1)
times = [x.strftime(TIME_FORMAT) for x in times] # Uses list comprehension to format the objects
print(times)

Checking date against date range in Python

In Python to check a range you can use a <= x <= b:

>>> import datetime
>>> today = datetime.date.today()
>>> margin = datetime.timedelta(days = 3)

>>> today - margin <= datetime.date(2011, 1, 15) <= today + margin
True

Compare the time of datetime.now() object with time string

The reason why your code is not working, it's because apart from time, datetime (as the name suggests) holds also information about the date.

When you run the following code:

timeStart = '0300'
timeStart = datetime.strptime(timeStart, '%H%M')

The hour and minute is converted, but the rest (the "date" part) is assumed to be epoch:

repr(timeStart)
# Output: 'datetime.datetime(1900, 1, 1, 3, 0)'

When you run datetime.now(), however, that always assumes the current time + date:

>>> datetime.now()
datetime.datetime(2020, 7, 17, 8, 25, 18, 270848)

The reason why converting to string, and back from string works, is because when you convert your datetime to a string with the format '%H%M, you lose the date part in the resulting string. Converting back from that, there's only hour and minutes to read, so you're losing the date part.

Effectivelly, you should be using datetime.time, instead of datetime.datetime to compare time.

After reading using strptime, try using the .time() method to only extract the time part and lose the date part:

timeStart = '0300'
timeStart = datetime.strptime(timeStart, '%H%M').time()

And same for the timeNow part:

timeNow = datetime.now().time()

Start a Function at a specific time range

You cannot directly set until condition as the day of week and time in schedule API but can set an explicit datetime, time, or a timedelta object as an argument in the until() function. See apidocs.

Also, you cannot schedule a job with a day of week and every x minutes.
Something like schedule.every(5).minutes.sunday.at("23:00") is not allowed.

Try something like this to first find the date of next Sunday then calculate the following Friday date from it. Now you have the starting and ending times.

Next, you can call sleep until the start time then you can start to schedule the job.

import time
from datetime import datetime, timedelta
import schedule

def script_sample():
now = datetime.now()
print(now)

now = datetime.now()
# find date of next sunday
d = now
# weekday(): Monday is 0 and Sunday is 6
while d.weekday() != 6:
d += timedelta(days=1)
d = d.replace(hour=23, minute=00, second=0, microsecond=0)
print("now=", now)
print("next sunday", d) # start date
wait_time = d - now

wait_time_secs = wait_time.total_seconds()
if wait_time_secs > 0:
print("wait time is ", wait_time)
print("waiting to start...")
time.sleep(wait_time_secs)
else:
print("no need to wait. let's get started')

This part of the code will be complete when it is Sunday at 23:00 or just late on Sunday if it was started on Sunday after 23:00.

Part 2 of the code below is to determine the until condition and schedule the job to run. Next find the date of next Friday which is the until condition in the schedule. Finally schedule the job to run every 5 minutes until Friday at 23:00.

# next find date of next Friday (friday=5)
while d.weekday() != 5:
d += timedelta(days=1)
endtime = d.replace(hour=23, minute=00, second=0, microsecond=0)
print("end time", endtime)

# now schedule a job every 5 mins until the end time
schedule.every(5).minutes.until(endtime).do(script_sample)

while True:
schedule.run_pending()


Related Topics



Leave a reply



Submit