Datetime comparison behavior in python - python

Hi I am writing a program that is dependent on time and observing some curious behavior with datetime objects I cannot quite figure out. The code I am working with / am having trouble with is...
now = datetime.now()
time_changed_state = some datettime object previously initialized
time_delay = some integer
time_arrival = time_changed_state + timedelta(minutes=time_delay)
if now < time_arrival:
do something
elif now >= time_arrival:
do something different
I have been working with test cases in order ot make sure the code behaves the way I would like it to but it doesn't seem to.
I discovered the odd behavior when the time_delay = 0, and I know for a fact that now would be >= time_arrival since time_changed_state was a datetime object initilizated before this function call and now was initialized within the function. However, the "do something" code is being executed rather than the "do something different code".
Thanks so much!

I've edited your code, is this what you are expecting?
from datetime import datetime
from datetime import timedelta
now = datetime.now()
time_changed_state = now - timedelta(hours=2)
time_delay = 0
time_arrival = time_changed_state + timedelta(minutes=time_delay)
if now < time_arrival:
print 'something'
elif now >= time_arrival:
print 'something different'

Related

How can I make a time string match up if the miliseconds do not match

I am trying to make a clock that stops at a certain time. This is the code I currently have:
import time as t
import datetime as dt
import os
tc = input("When do you want this to stop? (military time please) ")
exit = False
date = str(dt.datetime.now().date())
while (exit == False):
if dt.datetime.now() == date + " " + tc + ":00.0000":
exit = True
else:
print(dt.datetime.now())
t.sleep(0.01)
os.system('cls')
The problem is that the time never exactly gets to the perfect place for the parts less than a second so how do I get it to stop?
do you mean like this?
if dt.datetime.now() >= date + " " + tc + ":00.0000"
also please format the datetime.now() to the string you want
using something like datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
You could check if the time has passed, something like
if dt.datetime.now() >= date + " " + tc + ":00.0000":
You'll probably have to fiddle with the available methods to get it to work, I don't know if there's a built in comparator in that library. But something along those lines just checking if the current time is past the desired time.

This doesn't seem to work. No error message or anything, "time" just doesn't print. now and decisecond both show the right values.

Everything up here is fine
from datetime import datetime
while True:
now = str(datetime.now())
decisecond = now[20]
This part doesn't work
if decisecond == 1:
print(time)
It's because 'decisecond' isn't an int. Change the if statement to this, and it will work:
if int(decisecond) == 1:
print(time)
In saying that, printing 'time' will not print what I think you want it to. Probably change it to print the datetime, so the whole code is:
from datetime import datetime
while True:
now = str(datetime.now())
decisecond = now[20]
if int(decisecond) == 1:
print(datetime.now())

Python elasticsearch range query

I know that there are several alternative elasticsearch clients for python beyond this one. However, I do not have access to those. How can I write a query that has a 'less than or equal' logic for a timestamp? My current way of doing this is:
query = group_id:" + gid + '" AND data_model.fields.price:' + price
less_than_time = # datetime object
data = self.es.search(index=self.es_index, q=query, size=searchsize)
hits = data['hits']['hits']
results = []
for hit in hits:
time = datetime.strptime(hit['_source']['data_model']['utc_time'], time_format)
dt = abs(time - less_than_time).seconds
if dt <= 0:
results.append(hit)
This is a really clumsy way of doing it. Is there a way I can keep my query generation using strings and include a range?
I have a little script that generates a query for me. The query however is in the json notation (which I believe the client can use).
here's my script:
#!/usr/bin/python
from datetime import datetime
import sys
RANGE = '"range":{"#timestamp":{"gte":"%s","lt":"%s"}}'
QUERY = '{"query":{"bool":{"must":[{"prefix": {"myType":"test"}},{%s}]}}}'
if __name__ == "__main__":
if len(sys.argv) < 3:
print "\nERROR: 2 Date arguments needed: From and To, for example:\n\n./range_query.py 2016-08-10T00:00:00.000Z 2016-08-10T00:00:00.000Z\n\n"
sys.exit(1)
try:
date1 = datetime.strptime(sys.argv[1], "%Y-%m-%dT%H:%M:%S.%fZ")
date2 = datetime.strptime(sys.argv[2], "%Y-%m-%dT%H:%M:%S.%fZ")
except:
print "\nERROR: Invalid dates. From: %s, To: %s" %(sys.argv[1], sys.argv[2]) + "\n\nValid date format: %Y-%m-%dT%H:%M:%S.%fZ\n"
sys.exit(1)
range_q = RANGE %(sys.argv[1], sys.argv[2])
print(QUERY %(range_q))
The script also uses a bool query. It should be fairly easy to remove that and use only the time constraints for the range.
I hope this is what you're looking for.
This can be called and spits out a query such as:
./range_prefix_query.py.tmp 2016-08-10T00:00:00.000Z 2016-08-10T00:00:00.000Z
{"query":{"bool":{"must":[{"prefix": {"myType":"test"}},{"range":{"#timestamp":{"gte":"2016-08-10T00:00:00.000Z","lt":"2016-08-10T00:00:00.000Z"}}}]}}}
Artur
Take a look at https://elasticsearch-dsl.readthedocs.io/en/latest/
s = Search()\
.filter("term", **{"name": name})\
.query(q)\
.extra(**paging)

Python - Print index of for loop only once every five minutes

I'm trying to get a for loop to print the value of 'i' every 5 minutes
import threading
def f(i):
print(i)
threading.Timer(600, f).start()
for i in range(1,1000000000000):
f(i=i)
However, this method results in the code printing the value of i instantly since it calls 'f' as soon as it finds 'i'.
I know this is not the first time someone will ask, nor the last, but I can't get it to work on a for loop nested within a function.
I'm fairly new to Python and I'd appreciate any help.
How about just keeping track of how long has passed in the loop?
from timeit import default_timer as timer
start = timer()
freq = 5 * 60 # Time in seconds
last_time = 0.0
for i in range(int(1e8)):
ctime = timer()
if ctime - last_time > freq:
print(i)
last_time = ctime
I imagine you can make this more efficient by only checking the time every N iterations rather than every time. You may also want to look into using progressbar2 for a ready-made solution.
I prefer using datetime, as I think it's more intuitive and looks a bit cleaner. Otherwise, using more or less the same approach as Paul:
from datetime import datetime, timedelta
print_interval = timedelta(minutes=5)
# Initialize the next print time. Using now() will print the first
# iteration and then every interval. To avoid printing the first
# time, just add print_interval here (i.e. uncomment).
next_print = datetime.now() # + print_interval
for i in range(int(1e8)):
now = datetime.now()
if now >= next_print:
next_print = now + print_interval
print(i)
Also note that before python 3.x xrange would be preferable over range.

Automatically update stored value of datetime.datetime.now()

Here's my code, it's just supposed to basically change end to start + 25 minutes.
I'm just wondering if there is a way to update datetime.datetime.now() to be the current time.
As it stands, it just stays at whatever it was when I first used the module.
So the if statement will never be true.
import datetime
start = datetime.datetime.now()
end = start + datetime.timedelta(minutes = 25)
if start == end:
end = end + datetime.timedelta(minutes = 25)
As CharlesB has suggested, the start variable is not updated. You need to take the now value at the time you want to perform the test.
Rewrite the line:
if start == end:
To
if datetime.datetime.now() > end:
EDIT
After Tommo's comment, I think another solution may be easier.
import time
while True:
putMessageToScreen()
time.sleep(25*60)
If you want a value to change on subsequent references, you want to use a function call, not a stored variable.
In principle, you could make the above code do what you want by subclassing datetime.datetime and defining the __add__ method to recompute datetime.datetime.now(), but it wouldn't be a good idea.

Categories

Resources