How to extract time and store in an Array/Structure - python

I want to measure the time difference between two time readings in a Python script.
time_stamp_1 = datetime.datetime.now()
# some task
time_stamp_2 = datetime.datetime.now()
time_stamp = time_stamp_2 - time_stamp_1
time_stamp_sec = ??
I got the result as 0:00:04.052000.
What exactly is this time format I am getting?
How to extract the time in seconds from time_stamp?
How to store time_stamp in an array like variable (as I want to use a loop and store the time_stamp for each loop)
How to store time_stamp_sec in an array like variable

1) It's a datetime.timedelta object which is being printed nicely:
>>> import datetime
>>> datetime.timedelta(days=3)
datetime.timedelta(3)
>>> print(datetime.timedelta(days=3))
3 days, 0:00:00
>>> print(datetime.timedelta(hours=3))
3:00:00
2) You can use total_seconds():
>>> t = datetime.timedelta(hours=3)
>>> t.total_seconds()
10800.0
This gives you a float as the datetime.timedelta may represent an amount of time which isn't an exact number of seconds.
3) You can append it to a list at each step in the loop:
>>> d = []
>>> d.append(t)
>>> d
[datetime.timedelta(0, 10800)]
4) You can do the same with the result of total_seconds():
>>> e = []
>>> e.append(t.total_seconds())
>>> e
[10800.0]

Related

Convert list of time stamps from timedelta to readable string format

What I am trying to do is take two lists of time stamps, find the difference between the corresponding time stamp pairs, and then print the differences as another list. When I print the final list of time differences I get this:
[datetime.timedelta(0, 2700), datetime.timedelta(0, 1800)]
Here is my code for reference:
import time
import datetime
strlist1 = ['12:45:00', '01:30:00']
format = '%H:%M:%S'
i = 0
timelist1 = []
for time in strlist1:
timelist1.append(datetime.datetime.strptime(strlist1[i], format))
i += 1
strlist2 = ['12:00:00', '01:00:00']
k = 0
timelist2 = []
for time in strlist2:
timelist2.append(datetime.datetime.strptime(strlist2[k], format))
k += 1
list3 = [x1 - x2 for (x1, x2) in zip(timelist1, timelist2)]
Also, I am fairly new to Python, so any other constructive input on ways to improve and/or change anything else is greatly appreciated. Thank you!
List elements will use the repr, and the repr is not usually human readable.
>>> L = [datetime.timedelta(0, 2700), datetime.timedelta(0, 1800)]
>>> L
[datetime.timedelta(0, 2700), datetime.timedelta(0, 1800)]
You want:
>>> map(str, L) # or: [str(delta) for delta in L]
['0:45:00', '0:30:00']
This should give you a more readable format:
[((datetime.datetime.strptime('00:00:00', format))+e).strftime(format) for e in list3]
Out[340]: ['00:45:00', '00:30:00']
Here's a start. In Python there's no need for a counter when you iterate over a sequence, so the variables i and k are not needed. As wim pointed out, you probably want a string representation of the output. Finally, you can just generate the lists with a list comprehension instead of the loop.
import time
import datetime
strlist1 = ['12:45:00', '01:30:00']
format = '%H:%M:%S'
# i = 0 Not needed
timelist1 = [datetime.datetime.strptime(s, format) for s in strlist1]
strlist2 = ['12:00:00', '01:00:00']
timelist2 = [datetime.datetime.strptime(s, format) for s in strlist2]
list3 = [str(x1 - x2) for (x1, x2) in zip(timelist1, timelist2)]

Check if current current hour is available in python list

I have a variable with the operating time of a store:
t = '08:00-17:00'
Now, i need to check if the store is open now:
from time import gmtime, strftime
print strftime("%H:%M", gmtime())
#11:26
What is the most adequate way to make this? As side note, i can have t in minutes, or something more convenient.
Instead of trying to convert the current time into string, you should rather str.split() the t into two different times, and then convert them into datetime.datetime.time objects using datetime.datetime.strptime() , and then compare that with the time component on datetime.datetime.now() . Example -
import datetime
t = '08:00-17:00'
times = t.split('-')
start_time = datetime.datetime.strptime(times[0],'%H:%M').time()
end_time = datetime.datetime.strptime(times[1],'%H:%M').time()
if start_time <= datetime.datetime.now().time() <= end_time:
#Do you logic
Demo -
Closed time -
>>> import datetime
>>> t = '08:00-17:00'
>>> times = t.split('-')
>>> start_time = datetime.datetime.strptime(times[0],'%H:%M').time()
>>> end_time = datetime.datetime.strptime(times[1],'%H:%M').time()
>>> if start_time <= datetime.datetime.now().time() < end_time:
... print("Shop open")
...
>>>
Open time -
>>> t = '08:00-18:00'
>>> times = t.split('-')
>>> start_time = datetime.datetime.strptime(times[0],'%H:%M').time()
>>> end_time = datetime.datetime.strptime(times[1],'%H:%M').time()
>>> if start_time <= datetime.datetime.now().time() < end_time:
... print("Shop open")
...
Shop open
>>>
With this method even minutes are supported, you can change the format used to convert the time to a time object and support upto microseconds if you so wish.
First, you need to convert the t to a comparable value, such as a integer, so:
storeOpen, storeCloses = '08h00-17h00'.split('-')
This will split the string '08h00-17h00' into:
storeOpen => '08h00'
storeCloses => '17h00'
After that, you should transform the storeOpen and storeCloses into integer:
storeOpenHour, storeOpenMinutes = storeOpen.split('h') #splits the storeOpen into two
#converts to integer
storeOpenHour = int(storeOpenHour)
storeOpenMinutes = int(storeOpenMinutes)
#you should repeat the same process to storeClose
And then you just compare them:
if (nowMinutes > storeOpenMinutes and nowHour > storeOpenHour) and (nowMinutes < storeCloseMinutes and nowHour < storeCloseHour):
println "is open!"

Get date-time of directory and compare

import os
print(str(os.stat('/home/zarkopafilis/Python/test2.py').st_mtime))
Returns large values like :
1378906011.07
Within 5 seconds I run :
import datetime
now = datetime.datetime.now()
print(str(now.second))
It returns :
1-5(Depending how fast it runs)
How can I check the time that the file was created and see if X seconds have passed by the time script runs?
You can do the following:
>>> time_diff = time.time() - os.stat('/home/zarkopafilis/Python/test2.py').st_mtime
>>> hours, rest = divmod(time_diff, 3600)
>>> minutes, seconds = divmod(rest, 60)
>>> print hours
0.0
>>> print minutes
1.0
>>> print seconds
51.3503739834
Now that you have stored the time difference in the variables hours, minutes and seconds you can check if seconds >= X where X is the number of seconds you are interested in waiting for.
Hope this helps
1378906011.07 is the number that represent seconds from epoch (January 1st 1970).
You can see the time using datetime.datetime.fromtimestamp:
>>> import datetime
>>> datetime.datetime.fromtimestamp(1378906011.07)
datetime.datetime(2013, 9, 11, 22, 26, 51, 70000)
>>> print(datetime.datetime.fromtimestamp(1378906011.07))
2013-09-11 22:26:51.070000
Use time.time() to get current date-time as the second:
>>> time.time()
1378906919.446
>>> t1 = time.time()
>>> t2 = time.time() # a few second later
>>> t2 - t1
18.51900005340576
time.time() - os.stat('/home/zarkopafilis/Python/test2.py').st_mtime will give you passed time.

Parsing hh:mm in Python

Sometimes I get a string like "02:40" indicating 2 hours and 40 minutes. I'd like to parse that string into the number of minutes (160 in this case) using Python.
Sure, I can parse the string and multiply the hours by 60, but is there something in the standard lib that does this?
Personally, I think simply parsing the string is far easier to read:
>>> s = '02:40'
>>> int(s[:-3]) * 60 + int(s[-2:])
160
Note that using negative indexing means it will handle strings without the leading zero on the hour:
>>> s = '2:40'
>>> int(s[:-3]) * 60 + int(s[-2:])
160
You could also use the split() function:
>>> hours, minutes = s.split(':')
>>> int(hours) * 60 + int(minutes)
160
Or use the map() function to convert the pieces to integers:
>>> hours, minutes = map(int, s.split(':'))
>>> hours * 60 + minutes
160
Speed
Using the timeit module indicates it is also faster than other methods proposed here:
>>> import timeit
>>> parsetime = timeit.timeit("mins = int(s[:-3]) * 60 + int(s[-2:])", "s='02:40'", number=100000) / 100000
>>> parsetime
9.018449783325196e-06
The split() method is a bit slower:
>>> splittime = timeit.timeit("hours,minutes = s.split(':'); mins=int(hours)*60 + int(minutes)", "s='02:40'", number=100000)/100000
>>> splittime
1.1217889785766602e-05
>>> splittime/parsetime
1.2438822697120402
And using map() a bit slower again:
>>> splitmaptime = timeit.timeit("hours,minutes = map(int, s.split(':')); mins=hours*60 + minutes", "s='02:40'", number=100000)/100000
>>> splitmaptime
1.3971350193023682e-05
>>> splitmaptime/parsetime
1.5491964282881776
John Machin's map and sum is about 2.4 times slower:
>>> summaptime = timeit.timeit('mins=sum(map(lambda x, y: x * y, map(int, "2:40".split(":")), [60, 1]))', "s='02:40'", number=100000) / 100000
>>> summaptime
2.1276121139526366e-05
>>> summaptime/parsetime
2.43
Chrono Kitsune's strptime()-based answer is ten times slower:
>>> strp = timeit.timeit("t=time.strptime(s, '%H:%M');mins=t.tm_hour * 60 + t.tm_min", "import time; s='02:40'", number=100000)/100000
>>> strp
9.0362770557403569e-05
>>> strp/parsetime
10.019767557444432
Other than the following, string parsing (or if you want to be even slower for something so simple, use the re module) is the only way I can think of if you rely on the standard library. TimeDelta doesn't seem to suit the task.
>>> import time
>>> x = "02:40"
>>> t = time.strptime(x, "%H:%M")
>>> minutes = t.tm_hour * 60 + t.tm_min
>>> minutes
160
See http://webcache.googleusercontent.com/search?q=cache:EAuL4vECPBEJ:docs.python.org/library/datetime.html+python+datetime&hl=en&client=firefox-a&gl=us&strip=1 since the main Python site is having problems.
The function you want is datetime.strptime or time.strptime, which create either a datetime or time object from a string with a time and another string describing the format.
If you want to not have to describe the format, use dateutil, http://labix.org/python-dateutil.
from dateutil.parser import parse
>>> d = parse('2009/05/13 19:19:30 -0400')
>>> d
datetime.datetime(2009, 5, 13, 19, 19, 30, tzinfo=tzoffset(None, -14400))
See How to parse dates with -0400 timezone string in python?
>>> sum(map(lambda x, y: x * y, map(int, "2:40".split(":")), [60, 1]))
160
I'm sure you can represent the given time as a TimeDelta object. From there I am sure there is an easy way to represent the TimeDelta in minutes.
There is:
from time import strptime
from calendar import timegm
T = '02:40'
t = timegm(strptime('19700101'+T,'%Y%m%d%H:%M'))
print t
But is this really better than brute calculus ?
.
An exotic solution, that doesn't need importing functions :
T = '02:40'
exec('x = %s' % T.replace(':','*60+'))
print x
edit: corrected second solution to obtain minutes, not seconds
.
Simplest solution
T = '02:40'
print int(T[0:2])*60 + int(T[3:])

Adding up time durations in Python

I would like to add up a series of splits in Python. The times begin as strings like "00:08:30.291". I can't seem to find the right way to use the Python objects or API to make this convenient/elegant. It seems that the time object doesn't use microseconds, so I'm using datetime's strptime to parse the strings, successfully. But then datetimes don't seem to add, and I really prefer not to overflow into days (i.e. 23 + 2 hours = 25 hours). I can use datetime.time but they don't add either. Timedeltas would seem appropriate but seem a little awkward to convert from/to other things. Perhaps I am missing something obvious here. I would like to be able to:
for timestring in times:
t = datetime.strptime("%H:%M:%S.%f", timestring).time
total_duration = total_duration + t
print total_duration.strftime("%H:%M:%S.%f")
What you're working with is time differences, that's why using datetime.timedelta is only appropriate here:
>>> import datetime
>>> d1 = datetime.datetime.strptime("00:08:30.291", "%H:%M:%S.%f")
>>> d1
datetime.datetime(1900, 1, 1, 0, 8, 30, 291000)
>>> d2
datetime.datetime(1900, 1, 1, 0, 2, 30, 291000)
>>> dt1 = datetime.timedelta(minutes=d1.minute, seconds=d1.second, microseconds=d1.microsecond)
>>> dt2 = datetime.timedelta(minutes=d2.minute, seconds=d2.second, microseconds=d2.microsecond)
>>> fin = dt1 + dt2
>>> fin
datetime.timedelta(0, 660, 582000)
>>> str(fin)
'0:11:00.582000'
Also, please don't use such names as sum for your variables, you're shadowing built-in.
import numpy as np
# read file with one duration per line
with open('clean_times.txt', 'r') as f:
x = f.read()
# Convert string to list of '00:02:12.31'
# I had to drop last item (empty string)
tmp = x.split('\n')[:-1]
# get list of ['00', 02, '12.31']
tmp = [i.split(':') for i in tmp.copy()]
# create numpy array with floats
np_tmp = np.array(tmp, dtype=np.float)
# sum via columns and divide
# hours/24 minutes/60 milliseconds/1000
# X will be a float array [days, hours, seconds]
# Something like `array([ 0. , 15.68333333, 7.4189 ])`
X = np_tmp.sum(axis=0) / np.array([24, 60, 1000])
I was hapy here, but if you need fancy string like '15:41:07.518'
as output, continue reading
# X will be a float array [hours, hours, seconds]
X = np_tmp.sum(axis=0) / np.array([1, 60, 1000])
# ugly part
# Hours are integer parts
H = int(X[0]) + int(X[1])
# Minutes are hour fractional part and integer minutes part
tmp_M = (X[0] % 1 + X[1] % 1) * 60
M = int(tmp_M)
# Seconds are minutes fractional part and integer seconds part
tmp_S = tmp_M % 1 * 60 + X[2]
S = int(tmp_S)
# Milliseconds are seconds fractional part
MS = int(tmp_S % 1 * 1000)
# merge string for output
# Something like '15:41:07.518'
result = f'{H:02}:{M:02}:{S:02}.{MS:03}'

Categories