Python subsetting data by hour and minute, ignoring date - python

I have a list of image timestamps in the format '20121002_1639' ('%Y%m%d_%H%M')
I want to create a function that takes in a list of these timestamps and excludes images taken between
1500(3:00pm) and 1700 (5:00pm). However When I try to just parse the %H%M portion of the string, it automatically assigns those datetimes to the date 19000101_1500 and 19000101_1700. So I need to create objects which contain just hours and minutes but are not associated with a date.
The pseudo code would be something like this:
import datetime as dt
# example datetime string
datestrings = ['20121002_1639', '20111101_1229', '20160424_1502', '20170328_1100']
Start_time = dt.datetime.strptime('1500', '%H%M')
End_time = dt.datetime.strptime('1700', '%H%M')
good_times = []
for time in datestrings:
if dt.datetime.strptime(time[9:13], '%H%M') is between(Start_time, End_time):
continue
else:
good_times.append(time)

You may use only the time part from the datetime object, for that use the .time() method. So you don't need to parse only a part of the given string, parse all and then take it's time part too
datestrings = ['20121002_1639', '20111101_1229', '20160424_1502', '20170328_1100']
Start_time = dt.datetime.strptime('1500', '%H%M').time()
End_time = dt.datetime.strptime('1700', '%H%M').time()
good_times = []
for time in datestrings:
if not (Start_time <= dt.datetime.strptime(time, '%Y%m%d_%H%M').time() < End_time):
good_times.append(time)
print(good_times) # ['20111101_1229', '20170328_1100']
In fact you coud even do it with basic int comparisons
Start_time = 1500
End_time = 1700
for time in datestrings:
if not (Start_time <= int(time.split("_")[-1]) < End_time):
good_times.append(time)

Related

Python comparing to different time values to get time delta in minutes

I am trying to get get the time delta i minutes from two different time values.
time1 = 2020-11-28T10:31:12Z
time2 = 2020-11-28T09:10:23.203+0000
Then i will make i condition: if time difference is bigger then x minutes, run code...
Anyone have a solution for that.
I have tried using datetime.datetime.strptime() but cant get them on same format.
Thanks
Using date parser to let it figure out the date format
Code
from dateutil.parser import parse
def time_difference(time1, time2):
# Parse strings into datetime objects
dt1 = parse(time1)
dt2 = parse(time2)
# Get timedelta object
c = dt1 - dt2
# Difference in minutes
return (c.total_seconds()/60)
Test
time1 = "2020-11-28T10:31:12Z"
time2 = "2020-11-28T09:10:23.203+0000"
print(time_difference(time1, time2))
# Output: 80.81328333333333
well assuming you don't need split seconds you could do something like that:
time1 = '2020-11-28T10:31:12Z'
time2 = '2020-11-28T09:10:23.203+0000'
import time
import datetime
def get_timestamp(time_str):
time_splited = time_str.split('T')
time_str_formatted = ' '.join([time_splited[0],time_splited[1][:8]])
return time.mktime(datetime.datetime.strptime(time_str_formatted,"%Y-%m-%d %H:%M:%S").timetuple())
print(get_timestamp(time1))
print(get_timestamp(time2))
reformatting both times to the same time format.
then your condition would look like:
if abs(get_timestamp(time1) -get_timestamp(time2) ) > x*60:
do_something(....)
The times are not uniform so you will have to make them the same to use strptime. For accuracy I prefer to convert to seconds then you can also at a later stage compare seconds, minutes or hours if you needed to.
import datetime
time1 = '2020-11-28T10:31:12Z'
time2 = '2020-11-28T09:10:23.203+0000'
def minutes_diff():
#Make the times uniform so you can then use strptime
date_time1 = datetime.datetime.strptime(time1[:-1], "%Y-%m-%dT%H:%M:%S")
date_time2 = datetime.datetime.strptime(time2[:-9], "%Y-%m-%dT%H:%M:%S")
#Convert to seconds for accuracy
a_timedelta = date_time1 - datetime.datetime(1900, 1, 1)
b_timedelta = date_time2 - datetime.datetime(1900, 1, 1)
seconds_time_a = a_timedelta.total_seconds()
seconds_time_b = b_timedelta.total_seconds()
#Take one from each other for minutes
time_in_minutes = (seconds_time_a - seconds_time_b) / 60
#Then decide what to do with it
if time_in_minutes < 60: # 1 hour
print('Less than an hours do something')
else:
print('More than an hour do nothing')
minutes_diff()
DARRYL, JOHNNY and MARCIN, thanks for your solutions, problem solved!!
Andy

How to sum timestamps Python

I am using the awful library datetime and I trying to do what should be very easy. I have a collection of timestamps in my video file, and I want to simply subtract start_time from end_time and then take the sum of all and output, the total time of the video file. My data in my video file looks like this
<p begin="00:02:42.400" end="00:02:43.080" style="s2">product_1</p>
So my code,
start_time = dt.strptime(begin, '%H:%M:%S.%f')
endie_time = dt.strptime(end, '%H:%M:%S.%f')
diff += endie_time-start_time
What I am trying to do is to keep adding up 'diff'
I get this error,
UnboundLocalError: local variable 'diff' referenced before assignment
I think the error is because diff is a datetime object and it is not an integer. But then when I do `int(diff), nothing works.
How can I do this simple task? I appreciate any help I can get on this annoying problem.
Thanks
The fundamental issue here is that the datetime module deals with real-world wall clock times, whereas you're trying to deal with durations. The only really applicable class in the datetime module to deal with your problem appropriately is therefore timedelta, which essentially expresses durations. To parse your strings into a timedelta, you'll need to do so slightly manually:
>>> from datetime import timedelta
>>> h, m, s = '00:02:43.080'.split(':')
>>> timedelta(hours=int(h), minutes=int(m), seconds=float(s))
datetime.timedelta(seconds=163, microseconds=80000)
If you now have two such timedeltas, you can subtract them:
>>> end - start
datetime.timedelta(microseconds=680000)
And you can add them to an existing timedelta:
diff = timedelta()
diff += end - start
Complete example:
from datetime import timedelta
diff = timedelta()
def parse_ts(ts: str) -> timedelta:
h, m, s = ts.split(':')
return timedelta(hours=int(h), minutes=int(m), seconds=float(s))
timestamps = [('00:02:42.400', '00:02:43.080'), ...]
for start, end in timestamps:
diff += parse_ts(end) - parse_ts(start)
print(diff)
As the comments to the original question say, using
X += Y
requires that you have alredy defined X.
A possible fix would be:
import datetime as dt
diff = dt.timedelta(0) # Initialize the diff with 0
start_time = dt.datetime.strptime(begin, '%H:%M:%S.%f')
endie_time = dt.datetime.strptime(end, '%H:%M:%S.%f')
diff += endie_time-start_time # Accumulate the time difference in diff
Since it seems that you want to iterate over multiple star/end dates:
import datetime as dt
diff = dt.timedelta(0) # Initialize the diff with 0
for begin_i, end_i in zip(begin, end):
start_time = dt.datetime.strptime(begin_i, '%H:%M:%S.%f')
endie_time = dt.datetime.strptime(end_i , '%H:%M:%S.%f')
diff += endie_time-start_time # Accumulate the time difference in diff
In both cases above, diff will be of the dt.timedelta type.

Python convert GTFS time to datetime

It is common for a GTFS time to exceed 23:59:59 due to the timetable cycle. Ie, the last time may be 25:20:00 (01:20:00 the next day), so when you convert the times to datetime, you will get an error when these times are encountered.
Is there a way to convert the GTFS time values into standard datetime format, without splitting the hour out and then converting back to a string in the correct format, to then convert it to a datetime.
t = ['24:22:00', '24:30:00', '25:40:00', '26:27:00']
'0'+str(pd.to_numeric(t[0].split(':')[0])%24)+':'+':'.join(t[0].split(':')[1:])
For the above examples, i would expect to just see
['00:22:00', '00:30:00', '01:40:00', '02:27:00']
from datetime import datetime, timedelta
def gtfs_time_to_datetime(gtfs_date, gtfs_time):
hours, minutes, seconds = tuple(
int(token) for token in gtfs_time.split(":")
)
return (
datetime.strptime(gtfs_date, "%Y%m%d") + timedelta(
hours=hours, minutes=minutes, seconds=seconds
)
)
gives the following result
>>> gtfs_time_to_datetime("20191031", "24:22:00")
datetime.datetime(2019, 11, 1, 0, 22)
>>> gtfs_time_to_datetime("20191031", "24:22:00").time().isoformat()
'00:22:00'
>>> t = ['24:22:00', '24:30:00', '25:40:00', '26:27:00']
>>> [ gtfs_time_to_datetime("20191031", tt).time().isoformat() for tt in t]
['00:22:00', '00:30:00', '01:40:00', '02:27:00']
I didn't find an easy way, so i just wrote a function to do it.
If anyone else wants the solution, here is mine:
from datetime import timedelta
import pandas as pd
def list_to_real_datetime(time_list, date_exists=False):
'''
Convert a list of GTFS times to real datetime list
:param time_list: GTFS times
:param date_exists: Flag indicating if the date exists in the list elements
:return: An adjusted list of time to conform with real date times
'''
# new list of times to be returned
new_time = []
for time in time_list:
plus_day = False
hour = int(time[0:2])
if hour >= 24:
hour -= 24
plus_day = True
# reset the time to a real format
time = '{:02d}'.format(hour)+time[2:]
# Convert the time to a datetime
if not date_exists:
time = pd.to_datetime('1970-01-01 '+time, format='%Y-%m-%d')
if plus_day:
time = time + timedelta(days=1)
new_time.append(time)
return new_time

Python subtracting with time format

I have a df that looks like this:
Time_Start CODE time
0 2018-01-31 16:45:04.263 B76 2018-01-31 16:48:06
1 2018-01-31 16:10:26.000 974 2018-01-31 16:50:06
I am subtracting time from Time_Start. For the second one I get 39:49 which is the expected output but for the first one I get a number like 2.737000 (not what I want).
Time_Start is datetime64[ns] and time is object. This is how I am doing the conversion and subtracting:
waiting['time'] = pd.to_datetime(waiting['time'])
waiting['Duration'] = waiting['time'] - waiting['Time_Start']
waiting['Duration'] = waiting['Duration'].apply(lambda x: str(x)[-8:])
I am rather new to python so can someone tell me what am I doing wrong and why I am getting the 2 different outputs?
I am using python 2.x.
Full code:
query that returns the dataframe
.......
end_time = np_server_date.ix[0]['data'] """current time"""
end_time = end_time.strftime('%Y-%m-%d %H:%M:%S')
waiting['time'] = end_time """it's now the current time"""
waiting['time'] = pd.to_datetime(waiting['time'])
waiting['Duration'] = waiting['time'] - waiting['Time_Start']
waiting['Duration'] = waiting['Duration'].apply(lambda x: str(x)[-8:])
Alright so I think I have enough info to answer your question now.
Right of the bat, you'll need to create a connection with pyodbc.
Then, you'll want loop through your result set and then create datetime objects either through the constructor or using strptime() out of your two times.
Then, you'll subtract the datetime objects to get a difference between the times as a timedelta object.
Then, depending on what you need to do with that information, you can convert it to your format by doing some math.
import datetime
import pyodbc
#create connection
with pyodbc.connect(db, password) as cnxn:
#create cursor
cursor = cnxn.cursor()
cursor.execute('YOUR QUERY')
#loop through results
while true:
#use fetchone generator to optimize memory usage
row = cursor.fetchone()
#create datetime objects
start_time = datetime.strptime(row[0], '%Y-%m-%d %H:%M:%S.%f')
end_time = datetime.strptime(row[2], '%Y-%m-%d %H:%M:%S')
#the following creates a timedelta object
time_diff = end_time - start_time
#a couple ways to deal with the result
#printing time_diff yields Days:Seconds:Microseconds
#the following yields the difference in seconds
#difference = time_diff.totalseconds()
#alternatively, you can get days, seconds, microseconds.
#either way you have to do some math to convert to hours and
#minutes if desired
#difference = time_diff.days + ":" + time_diff.seconds + ":"
# + time_diff.microseconds
#TODO your division to format the seconds how you'd like
#using divmod, you can get hours, min, second
m, s = divmod(time_diff.seconds, 60)
h, m = divmod(m, 60)
print "%d:%d:%02d:%02d" % (time_diff.days, h, m, s)
#TODO whatever you need to do with this information
if not row:
break

String to time python in hours and minutes and calculate difference

I am taking time as input from the user in the HH:MM format. Let's say 00:00 and now I want to keep adding a minute to the time and make it 00:01, 00:02 and so on.
Also, I am taking two inputs form the user start_time and end_time as strings. How can I calculate the difference between the two times as well in minutes?
I am new to Python and any help would be appreciated!
I am using the below code:
#to calculate difference in time
time_diff = datetime.strptime(end_time, '%H:%M') - datetime.strptime(start_time, '%H:%M')
minutes = int(time_diff.total_seconds()/60)
print minutes
#to convert string to time format HH:MM
start_time = datetime.strptime(start_time, '%H:%M').time()
#to increment time by 1 minute
start_time = start_time + datetime.timedelta(minutes=1)
I am not able to increment the start_time using timedelta.
import datetime
time_diff = datetime.datetime.strptime(end_time, '%H:%M') - datetime.datetime.strptime(start_time, '%H:%M')
minutes = int(time_diff.total_seconds()/60)
print minutes
datetime is a class of the datetime module that has a classmethod called strptime. The nomenclature is a bit confusing, but this should work as you intend it to.
As for adding a time delta, you'll need store the start time as a datetime object in order to get that to work:
start_datetime = datetime.datetime.strptime(start_time, '%H:%M')
start_datetime = start_datetime + datetime.timedelta(minutes=1)
print start_datetime
First part of your question, you can use the datetime module:
from datetime import datetime as dt
from datetime import timedelta as td
UsrInput = '00:00'
fmtString = '%H:%M'
myTime = dt.strptime(UsrInput, fmtString)
increment = td(0,1)
for count in range(10):
myTime += increment
print (dt.strftime(myTime, fmtString))
Second part will also use datetime, as such:
from datetime import datetime as dt
from datetime import timedelta as td
start_time = '00:01'
end_time = '00:23'
fmtString = '%H:%M'
myStart = dt.strptime(start_time, fmtString)
myEnd = dt.strptime(end_time, fmtString)
difference = myEnd - myStart
print(td.strftime(difference, '%M')

Categories

Resources