best way to add unpredictable time strings in python3? - python

a project I'm building takes different time lengths from album tracklists in as strings, and I want to add them up cumulatively. The inputs can vary in unpredictability, such as the following list of input time strings:
inputs = ['0:32', '3:19', '11:22']
So I would want to add all these times up like so:
0:32 + 3:19 + 11:22 = = 15:13
I need to make sure the resulting time is a valid timestamp, so incrementing the second/minute/hours realistically is necessary
I figured the best way to do this would be to convert each string time to a python datetime object, but I'm having trouble thinking of how to do this realistically, since all my knowledge and examples I can find of converting a string to a datetime use hard-coded datetime templates, such as:
datetime_str = '09/19/18 13:55:26'
datetime_object = datetime.strptime(datetime_str, '%m/%d/%y %H:%M:%S')
I need to identify multiple different possible string-times, such as :
0:32 = %m:%S
23:19 = %M:%S
01:22:23 = %H:%M:%S
01:2:23 = %H:%m:%S
is there a way to automate this process of adding up multiple different timestamps? My thought process was take the time-string, convert to datetime, convert that datetimeObject to seconds, add them up, then convert it back to dateTime HH:MM:SS format. But I'm getting hung up on how many different possible time inputs I can receive. Any advice is much appreciated as to how I can solve this problem

If you know that they all follow this format, it should be doable to parse manually:
def add_times(inputs):
total_secs=0
for input in inputs:
chunks = map(int, reversed(input.split(':')))
total_secs += sum(chunk*60**i for i,chunk in enumerate(chunks))
return "{}:{}:{}".format(total_secs//3600, (total_secs%3600)//60, total_secs%60)
print(add_times( ['0:32', '3:19', '11:22']))
gives me 0:15:13.

For durations, please work with datetime.timedelta. Here’s how to parse your strings into a timedelta, illustrated step by step:
>>> '5:13'.split(':')
['5', '13']
>>> list(map(int, '5:13'.split(':')))
[5, 13]
>>> list(zip(('seconds', 'minutes', 'hours'), map(int, reversed('5:13'.split(':')))))
[('seconds', 13), ('minutes', 5)]
>>> dict(zip(('seconds', 'minutes', 'hours'), map(int, reversed('5:13'.split(':')))))
{'seconds': 13, 'minutes': 5}
>>> timedelta(**dict(zip(('seconds', 'minutes', 'hours'), map(int, reversed('5:13'.split(':'))))))
datetime.timedelta(seconds=313)
Then add up your timedeltas:
from datetime import timedelta
from functools import reduce
from operator import add
def to_timedelta(duration: str) -> timedelta:
return timedelta(**dict(zip(('seconds', 'minutes', 'hours'), map(int, reversed(duration.split(':'))))))
inputs = ['0:32', '3:19', '11:22']
print(reduce(add, map(to_timedelta, inputs)))
# 0:15:13
A timedelta automatically formats in a nice "H:M:S" format when converted to a string, so there isn't much more you need to do.

Related

Converting timezone to new format and inserting into list in python [duplicate]

I'm adding UTC time strings to Bitbucket API responses that currently only contain Amsterdam (!) time strings. For consistency with the UTC time strings returned elsewhere, the desired format is 2011-11-03 11:07:04 (followed by +00:00, but that's not germane).
What's the best way to create such a string (without a microsecond component) from a datetime instance with a microsecond component?
>>> import datetime
>>> print unicode(datetime.datetime.now())
2011-11-03 11:13:39.278026
I'll add the best option that's occurred to me as a possible answer, but there may well be a more elegant solution.
Edit: I should mention that I'm not actually printing the current time – I used datetime.now to provide a quick example. So the solution should not assume that any datetime instances it receives will include microsecond components.
If you want to format a datetime object in a specific format that is different from the standard format, it's best to explicitly specify that format:
>>> import datetime
>>> datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
'2011-11-03 18:21:26'
See the documentation of datetime.strftime() for an explanation of the % directives.
Starting from Python 3.6, the isoformat() method is flexible enough to also produce this format:
datetime.datetime.now().isoformat(sep=" ", timespec="seconds")
>>> import datetime
>>> now = datetime.datetime.now()
>>> print unicode(now.replace(microsecond=0))
2011-11-03 11:19:07
In Python 3.6:
from datetime import datetime
datetime.now().isoformat(' ', 'seconds')
'2017-01-11 14:41:33'
https://docs.python.org/3.6/library/datetime.html#datetime.datetime.isoformat
This is the way I do it. ISO format:
import datetime
datetime.datetime.now().replace(microsecond=0).isoformat()
# Returns: '2017-01-23T14:58:07'
You can replace the 'T' if you don't want ISO format:
datetime.datetime.now().replace(microsecond=0).isoformat(' ')
# Returns: '2017-01-23 15:05:27'
Yet another option:
>>> import time
>>> time.strftime("%Y-%m-%d %H:%M:%S")
'2011-11-03 11:31:28'
By default this uses local time, if you need UTC you can use the following:
>>> time.strftime("%Y-%m-%d %H:%M:%S", time.gmtime())
'2011-11-03 18:32:20'
Keep the first 19 characters that you wanted via slicing:
>>> str(datetime.datetime.now())[:19]
'2011-11-03 14:37:50'
I usually do:
import datetime
now = datetime.datetime.now()
now = now.replace(microsecond=0) # To print now without microsecond.
# To print now:
print(now)
output:
2019-01-13 14:40:28
Since not all datetime.datetime instances have a microsecond component (i.e. when it is zero), you can partition the string on a "." and take only the first item, which will always work:
unicode(datetime.datetime.now()).partition('.')[0]
As of Python 3.6+, the best way of doing this is by the new timespec argument for isoformat.
isoformat(timespec='seconds', sep=' ')
Usage:
>>> datetime.now().isoformat(timespec='seconds')
'2020-10-16T18:38:21'
>>> datetime.now().isoformat(timespec='seconds', sep=' ')
'2020-10-16 18:38:35'
We can try something like below
import datetime
date_generated = datetime.datetime.now()
date_generated.replace(microsecond=0).isoformat(' ').partition('+')[0]
>>> from datetime import datetime
>>> dt = datetime.now().strftime("%Y-%m-%d %X")
>>> print(dt)
'2021-02-05 04:10:24'
f-string formatting
>>> import datetime
>>> print(f'{datetime.datetime.now():%Y-%m-%d %H:%M:%S}')
2021-12-01 22:10:07
This I use because I can understand and hence remember it better (and date time format also can be customized based on your choice) :-
import datetime
moment = datetime.datetime.now()
print("{}/{}/{} {}:{}:{}".format(moment.day, moment.month, moment.year,
moment.hour, moment.minute, moment.second))
I found this to be the simplest way.
>>> t = datetime.datetime.now()
>>> t
datetime.datetime(2018, 11, 30, 17, 21, 26, 606191)
>>> t = str(t).split('.')
>>> t
['2018-11-30 17:21:26', '606191']
>>> t = t[0]
>>> t
'2018-11-30 17:21:26'
>>>
You can also use the following method
import datetime as _dt
ts = _dt.datetime.now().timestamp()
print("TimeStamp without microseconds: ", int(ts)) #TimeStamp without microseconds: 1629275829
dt = _dt.datetime.now()
print("Date & Time without microseconds: ", str(dt)[0:-7]) #Date & Time without microseconds: 2021-08-18 13:07:09
Current TimeStamp without microsecond component:
timestamp = list(str(datetime.timestamp(datetime.now())).split('.'))[0]

Convert string to timestamp python

I'm trying to convert the list of str to the list of timestamps, then want to create the list of time delta of timestamps using total_seconds()
from datetime import datetime
a = ['091122333','092222222','093333333']
for i in a:
datetime.strptime(str(i),'%H:%M:%S.%f')
print(a)
It shows the error code of time data '091122333' does not match format '%H:%M:%S.%f'
I want to make timestamp 09(%H)11(%M)22(%S)333(%F) if possible.
Could you give me the advice above?
Thank you very much...
You have to first change the representation ( You have : which is not present in list of string in a) and how You manage what is returned from datetime.strptime (You have to store the value while You iterate through list) like that:
from datetime import datetime
a = ['091122333','092222222','093333333']
for t in range(len(a)):
a[t] = datetime.strptime(a[t],'%H%M%S%f')
delta = a[1]-a[0]
print(delta.total_seconds())
The format passed to strptime should represent the format used in the string (there are no colons in your string):
from datetime import datetime
a = ['091122333', '092222222', '093333333']
for i in a:
dt = datetime.strptime(str(i), '%H%M%S%f')
print(dt)
Out:
1900-01-01 09:11:22.333000
1900-01-01 09:22:22.222000
1900-01-01 09:33:33.333000

converting a list of string with the format 68.830320 in 'time' format without date information. The time format is second.millisecond

I have a string in the form of 68.830320 Format. this I need to convert to time Format in second.millisecond. it does not contain date or any other values. I cannot use strptime since the Format is not right. tstamp that I'm trying to parse is a list of calues containg values with decimal Point. I cannot round this value. it still gives error. I'm not sure how to proceeed. please help!
tried a lot of threads from here that always take the datetime object. But since my Format is not in the same way, I cannot use that info. I have tries .time dateutil, and everything else available. I still cannot solve this problem
tstamp = child2.get('timestamp').replace(" ", "").replace("\n", "")
print(tstamp)
parser.parser(tstamp)
format_time = datetime.date(tstamp)
print(format_time)
A number of seconds isn't a datetime, it's a timedelta. It isn't a datetime because you can't take the string "68.830320" and set the hands on a wall clock to represent that time.
Convert your string to a timedelta like this:
>>> from datetime import timedelta
>>> mytime = timedelta(seconds=float("68.830320"))
>>> mytime
datetime.timedelta(0, 68, 830320)
You can then add the timedelta to a datetime to get a wall clock time.

Slicing and Replacing Unicode String Characters

I have the following loop I'm trying to use to replace characters in a unicode string. The data I'm getting for this loop is in the following format: YYYY-MM-DD HH:MM:SS
This data is apparently stored in UTC, so when I grab it and append these times & dates to my list appts_list its 4 hours ahead.
I've gotten as far as slicing the unicode string and doing the math on these characters and getting what would be the correct hour I need, but I'm having a problem getting that back into a string so I can write it to my list appts_list.
I'm getting TypeError when I try to write the integer for the correct hour time_slice_int back into the original string. I decided to try to put the entire string into a list and change them there, but that isn't working either.
Ideally I want an appointment for '2013-06-28 15:30:00' to be entered into my appts_list as '2013-06-28 11:30:00'.
The print statements are there for me to debug as I ran it. They are not necessary for the final version.
Anyone have any suggestions or solutions?
for appt in todays_appts:
time = appt['apptdateourtime_c']
time_slice = time[11:13]
time_slice_int = int(time_slice)
time_slice_int -= 4
print(time_slice_int)
appt_time = list(time)
print(appt_time)
print(appt_time[11:13])
#appt_time[11:13] = time_slice_int
#appts_list.append()
print('AppointmentScheduled')
#print(appt['apptdateourtime_c'])
#print(time)
print('')
You should use the datetime module here:
>>> from datetime import datetime, timedelta
>>> strs = '2013-06-28 15:30:00'
>>> d = datetime.strptime(strs, "%Y-%m-%d %H:%M:%S")
datetime.strptime returns a datetime object:
>>> d
datetime.datetime(2013, 6, 28, 15, 30)
>>> d.hour
15
>>> d.month
6
Now decrease 4 hours from the above datetime object(d) using timedelta and assign the new object to a variable:
>>> d1 = d - timedelta(hours = 4)
Now use datetime.strftime to get a string of required format:
>>> datetime.strftime(d1,"%Y-%m-%d %H:%M:%S")
'2013-06-28 11:30:00'

Getting a lists of times in Python from 0:0:0 to 23:59:59 and then comparing with datetime values

I was working on code to generate the time for an entire day with 30 second intervals. I tried using DT.datetime and DT.time but I always end up with either a datetime value or a timedelta value like (0,2970). Can someone please tell me how to do this.
So I need a list that has data like:
[00:00:00]
[00:00:01]
[00:00:02]
till [23:59:59] and needed to compare it against a datetime value like 6/23/2011 6:38:00 AM.
Thanks!
Is there a reason you want to use datetimes instead of just 3 for loops counting up? Similarly, do you want to do something fancy or do you want to just compare against the time? If you don't need to account for leap seconds or anything like that, just do it the easy way.
import datetime
now = datetime.datetime.now()
for h in xrange(24):
for m in xrange(60):
for s in xrange(60):
time_string = '%02d:%02d:%02d' % (h,m,s)
if time_string == now.strftime('%H:%m:%S'):
print 'you found it! %s' % time_string
Can you give any more info about why you are doing this? It seems like you would be much much better off parsing the datetimes or using strftime to get what you need instead of looping through 60*60*24 times.
There's a great answer on how to get a list of incremental values for seconds for a 24-hour day. I reused a part of it.
Note 1. I'm not sure how you're thinking of comparing time with datetime. Assuming that you're just going to compare the time part and extracting that.
Note 2. The time.strptime call expects a 12-hour AM/PM-based time, as in your example. Its result is then passed to time.strftime that returns a 24-hour-based time.
Here's what I think you're looking for:
my_time = '6/23/2011 6:38:00 AM' # time you defined
from datetime import datetime, timedelta
from time import strftime, strptime
now = datetime(2013, 1, 1, 0, 0, 0)
last = datetime(2013, 1, 1, 23, 59, 59)
delta = timedelta(seconds=1)
times = []
while now <= last:
times.append(now.strftime('%H:%M:%S'))
now += delta
twenty_four_hour_based_time = strftime('%H:%M:%S', strptime(my_time, '%m/%d/%Y %I:%M:%S %p'))
twenty_four_hour_based_time in times # returns True

Categories

Resources