pycron
pycron copied to clipboard
has been fails oftend if timeframe start and end stemps differ less than a minute.
from datetime import datetime
import pycron
if __name__ == "__main__":
start_as_string = "2022-12-02 16:32:57.382138"
end_as_string = "2022-12-02 16:33:01.459094"
format = "%Y-%m-%d %H:%M:%S.%f"
start_time = datetime.strptime(start_as_string, format)
end_time = datetime.strptime(end_as_string, format)
cron_expression = "15,33,59 * * * *"
print(pycron.has_been(cron_expression, start_time, dt=end_time))
-> Returns False
This is a bug, right? It shall return true because minute 33 is in the time window (16:33:01.459094) Why does it return False?
My idea: Iterate over seconds
def has_been(s, since, dt=None):
if dt is None:
dt = datetime.now(tz=since.tzinfo)
if dt < since:
raise ValueError("The since datetime must be before the current datetime.")
while since <= dt:
if pycron.is_now(s, since):
return True
since += timedelta(seconds=1)
return False
But with this implementation
start_as_string = "2022-12-02 16:32:59.999999"
end_as_string = "2022-12-02 16:33:00.00001"
Would still return false.
How about that?
# own implementation of has been, that respects seconds.
def has_been(s, since, dt=None):
if dt is None:
dt = datetime.now(tz=since.tzinfo)
if dt < since:
raise ValueError("The since datetime must be before the current datetime.")
while since <= dt:
if pycron.is_now(s, since):
return True
if (dt-since).total_seconds() < 1:
since = dt
else:
since += timedelta(seconds=1)
return False
It also works in case of:
start_as_string = "2022-12-02 16:32:59.999999"
end_as_string = "2022-12-02 16:33:00.00001"
Ok, that can lead to infinite looping :(
testing now this:
# own implementation of has been, that respects seconds.
def has_been(s, since, dt=None):
if dt is None:
dt = datetime.now(tz=since.tzinfo)
if dt < since:
raise ValueError("The since datetime must be before the current datetime.")
while since <= dt:
if pycron.is_now(s, since):
return True
if (dt-since).total_seconds() < 1:
since = dt
if pycron.is_now(s, since):
return True
else:
return False
else:
since += timedelta(seconds=1)
return False