How to compare a datetime object to a certain amount of time? - python

I am trying to write a program to keep track of the errors. I am storing the first time an error occured and the last time. If the error continues to occur for 45 seconds, I will create an alert but the alert is not the part of my question.
I need to write an if statement to compare 2 datetime objects and take the difference in seconds. Then, if the difference is more than 45 seconds, I will create an alert.
My issue is I couldn't find out how to compare the difference between two datetime objects to a certain amount of time.
All the examples on the web including other StackOverFlow questions are just doing comparisons like if today < yesterday: do something but that doesn't help me because I don't know what will be one side of the comparison.
The time objects I am dealing with are as follows:
errors[oneEquity]['StartTime'] = 12:32:44
errors[oneEquity]['LastTime'] = 12:32:50
I found out from other questions that I can get the difference as follows:
errors[oneEquity]['LastTime'] - errors[oneEquity]['StartTime'] = 0:00:06
I believe that the difference is a datetime object, too. Now, I need to compare that object to 45 seconds but I don't know how to state 45 seconds.
Is it going to be a datetime object? If so, how can I create a datetime object of 45 seconds?
The if-statement I should write is something like that:
if errors[oneEquity]['LastTime'] - errors[oneEquity]['StartTime'] > (45 seconds):
# create an alert

from datetime import datetime
from datetime import timedelta
error_occurs = datetime.now() - timedelta(seconds=45)
# error_occurs = datetime.now() - timedelta(seconds=44)
if datetime.now() - error_occurs >= timedelta(seconds=45):
print('works')
** delta could be constant

Related

Check whether input time falls in given time range in python 3

Can someone explain to me, how to check whether a given time in "hh:mm" format falls in between a given range.
Say, given time is 10:30 A.M IST and my range is between 10:00 A.M and 11:00 A.M. So given time falls in the range.
Is there any package in python to do this in the easiest way?
Would be happy if anyone can help with this :)
The simple way is just to use datetime.time and compare in an if statement:
import datetime
hhmm = "10:30"
current_time = datetime.datetime.strptime(hhmm, "%H:%M").time()
if datetime.time(10) <= current_time <= datetime.time(11):
print("Time is between 10am and 11am")
else:
print("Time is not between 10am and 11am")
The timezone info is removed from the datetime object when .time() is called on it - if you input a literal time without a timezone, this isn't an issue, while if you do have a timezone then as long as the datetime is transformed (via .astimezone(zoneinfo.ZoneInfo('IST'))) into the timezone you want, you should just be able to compare with the literal 10am and 11am.
See also strptime() behavior, if your input format is more complicated than the above. It's possible to accommodate for AM/PM, as well as timezone.

Python get total seconds from datetime results in occasional mistakes

I'm trying to follow these answers and get the elapsed seconds since Jan 1st 1970 for each element in my array (my_times). I'm then using these values to find the time intervals between each consecutive time. Either approach I take seems to give the wrong answer for at least one pair of times.
Mark Byers answer
To get the seconds since Jan 1st 1970, he suggested to try:
time.mktime(my_time.timetuple())
However this does not seem to work for times "2017-11-05 01:46:00+00" and "2017-11-05 01:47:00+00".
When I run the below code, it says the values are separated by 3660.0 seconds instead of 60.0 seconds
from datetime import datetime
import time
my_time1 = datetime.strptime("2017-11-05 01:46:00+00", "%Y-%m-%d %H:%M:%S+%f")
my_time2 = datetime.strptime("2017-11-05 01:47:00+00", "%Y-%m-%d %H:%M:%S+%f")
time.mktime(my_time2.timetuple()) - time.mktime(my_time1.timetuple())
Andrzej Pronobis' answer
To get the seconds since Jan 1st 1970, he suggested to try:
my_time.timestamp()
This fixed the two earlier times however it no longer works for times "2017-11-05 01:59:00+00" and "2017-11-05 02:00:00+00". The same issue appears, I get 3660.0 seconds instead of 60.0 seconds
from datetime import datetime
my_time1 = datetime.strptime("2017-11-05 01:59:00+00", "%Y-%m-%d %H:%M:%S+%f")
my_time2 = datetime.strptime("2017-11-05 02:00:00+00", "%Y-%m-%d %H:%M:%S+%f")
my_time2.timestamp() - my_time1.timestamp()
I'd like to know if I'm doing anything wrong? Also is there a better way to find all consecutive time intervals when the datetime is given as a String?
Edit:
Thank you John, that fixed the problem. Oddly, changing the format from +%f to %z still ran into the same issue.
What did work was running sudo ln -sf /usr/share/zoneinfo/UTC /etc/localtime (changes my computer's time to UTC) and then evaluating all the times
This is a case of "garbage in, garbage out." Here:
datetime.strptime("2017-11-05 01:59:00+00", "%Y-%m-%d %H:%M:%S+%f")
You probably think that +00 on the end means "UTC time", but the %f format specifier means "fractional seconds."
In any case, you're apparently running on a system where the time zone is set to one with daylight saving time part of the year. 2 AM happens twice on the DST changeover date in November, so your code is working as written (it's ambiguous, basically).
Put another way: your issue is not that you're computing time deltas incorrectly. Your issue is that you are loading the times from strings incorrectly (or ambiguously).

Python - how to run function at a certain PST/PDT time?

I'm beginning to learn python and I've tried to create a script to run a certain command at a certain time. This is what I have so far:
import datetime
day_of_week = datetime.date.today().weekday() # 0 is Monday, 6 is Sunday
time = datetime.datetime.now().time()
if day_of_week == 4 and (time >= datetime.time(2,45) and time < datetime.time(9)):
#do something
elif (day_of_week == 3 and time > datetime.time(22)) or (day_of_week == 4 and time < datetime.time(2,45)):
#wait until 2h45
else:
#do nothing
I want the script to continue only on a certain day and when it's around 19h00 PST/PDT (2h45 GMT/UTC). The one I wrote works fine with GMT/UTC, but I'm certain that it will fail when daylight savings starts or if I change the local timezone to a different one.
What could I do to make the script check for the current time in PST/PDT and continue from there, ignoring or converting the local timezone?
#Ruben, please try this code below. It always look at the time in US/Pacific timezone. Hope it helps. Thanks.
import datetime
import pytz
pst_timezone = pytz.timezone("US/Pacific")
time=datetime.datetime.now(pst_timezone).time()
print(time)
Result: 12:13:10.136603
You should look into pytz
Python: display the time in a different time zone will be helpful too
Pythons Datetime pulls from the system time. So if the system is setup to use DST then you will be fine.
If you don't or cant trust the system time then no build in function will be accurate. You will then need to have your program go out and pull time from another server.

using unix timestamp generate timedelta for babel's format_timedelta

I am not sure I worded that correctly but python and time always confuses me.
This is what I am trying.
Given a unix timestamp (INT) which is definitely in the past (can be seconds ago or years ago) I want to generate a babel format_timedelta
My problem is
Babel format_timedelta takes timedelta as first argument
so I guess I need to generate a timedelta using time.time() (now) and the unix timestamp I have.
I can't figure out the part 2 and I believe there must be an easier/correct way to do this. Please share the best possible way to do this, also I need it to be fast in calculating since I have to use it in a web page.
def format_starttime(value, granularity="day"):
delta = datetime.timedelta(seconds=time.time() - value)
return format_timedelta(delta, granularity)
gives error in date.format_timedelta()
AttributeError: 'module' object has no attribute 'format_timedelta'
import datetime
td = datetime.timedelta(seconds=time.time()-a_unix_timestamp)
Difference between two datetime instances is a timedelta instance.
from datetime import datetime
from babel.dates import format_timedelta
delta = datetime.now() - datetime.fromtimestamp(your_timestamp)
print format_timedelta(delta, locale='en_US')
See datetime module documentation for details and more examples.

Python datetime subtracting date oddity

I have a datetime object created from which I subtract 13 days as follow:
(date.today()-timedelta(days=13)).strftime('%Y-%m-%d')
The strangeness occurs when I execute the code at 6AM and 8:30AM. At 6AM, the resulting string is returned as (if today is 2012-02-29):
2012-02-15
which is 14 days before the current! However, running the same line at 8:30AM, the resulting string is returned as:
2012-02-16
Which then correct. So far I have not been able to figure out what the difference is between the small period of time. I use timezone naive datetime objects, if that is important. I would like to know what could cause this change in the resulting string date.
Many thanks.
EDIT: (based on eumiro's suggestion below)
datetime.datetime.now() returns:
>>> datetime.datetime(2012, 2, 29, 10, 46, 20, 659862)
And the timezone is Europe/Vienna on the server and in the django application that runs the line of code.
I also tried running a similar line to the one you suggested:
(pytz.timezone(settings.TIME_ZONE).localize(datetime.now(), is_dst=True) - \
timedelta(days=13)).strftime('%Y-%m-%d')
But with the same results... which is why I think I don't think it has much to do with timezones also. But at the same time not sure where else to look.
You live somewhere in America? This is the place where the timezones are around 6-8 hours behind the UTC and that's the time of UTC midnight.
What does datetime.datetime.now() return?
If you want to get the real local time, use this (replace "America/New_York" with your timezone):
from datetime import datetime, timedelta
import pytz
now = datetime.datetime.now(pytz.timezone("America/New_York"))
dt = (now - timedelta(days=13)).strftime('%Y-%m-%d')
and it should return the same correct values from midnight until midnight.
Unfortunately DST is poorly supported in Python.
Even pytz is not perfect, but can be made to work with hacks.
You have to decide what it means to subtract 2 days from 10th, 1p.m., either 2 calendar days or 48 hours or 172800 seconds.

Categories