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
How to Center a Window on the Screen in Tkinter
How to Create Multiple Data Frames Using a for Loop in Python
How to Make an Auto Increment Integer Field in Django
Determining Neighbours of Cell Two Dimensional List
How to Write to an Existing Excel File Without Overwriting Data (Using Pandas)
Removing White Space Around a Saved Image
Find Largest Number from User Input
How to Adjust Padding With Cutoff or Overlapping Labels
How to Update Sqlalchemy Orm Object by a Python Dict
Typeerror: Missing 1 Required Positional Argument: 'Self'
How to Convert Column With String Type to Int Form in Pyspark Data Frame
What Causes a Python Segmentation Fault
Python Dataframe Query With Spaces in Column Name
Centering Text in Ipython Notebook Markdown/Heading Cells
Converting a Numpy Array into a Dict of Values Mapped to Rows
Why Calling .Sort() Function on Pandas Series Sorts Its Values In-Place and Returns Nothing