Posts: 414
Threads: 111
Joined: Apr 2020
Hi, I have a very tricky (for me) time conversion.
I have string:
Start time, End Time, Total Time, other stuff, more stuff, more stuff, and more
2020-11-02 16:53:14, 2020-11-03 08:41:47, 15:48:33, JP04TNNV0015EN, Bell_13, TT_Dev, TG LK A
I need to split the total time between two days so I'll get two strings like this:
2020-11-02 16:53:14, 2020-11-03 00:00:00, 07:07:46,JP04TNNV0015EN,Bell_13, TT_Dev,TG LK A
2020-11-03 00:00:00, 2020-11-03 08:41:47, 08:41:47,JP04TNNV0015EN,Bell_13, TT_Dev,TG LK A
Sometimes I need to split total time between two, three, or more days.
I'm not sure how to even start.
Thank you again!
Posts: 12,031
Threads: 485
Joined: Sep 2016
Posts: 414
Threads: 111
Joined: Apr 2020
Done that.
from datetime import datetime, date, time, timedelta
fmt = '%Y-%m-%d %H:%M:%S'
tstamp1 = datetime.strptime(lsn, fmt)
tstamp2 = datetime.strptime(fln, fmt)
if tstamp1 > tstamp2:
td = tstamp1 - tstamp2
tdif = str(td) what I'm asking is different  , I googled for a couple of days  before asking for help
Thank you.
Posts: 12,031
Threads: 485
Joined: Sep 2016
Nov-05-2020, 01:31 PM
(This post was last modified: Nov-05-2020, 01:31 PM by Larz60+.)
what have you tried so far?
Please post code, Thank you
Also, are you reading data from a file?
Posts: 1,950
Threads: 8
Joined: Jun 2018
Maybe I am missing something but I would start by determining whether and/or how many splits I should make (difference in days) and then split time accordingly.
>>> import datetime
>>> start = datetime.datetime(2020, 11, 5, 16, 34, 48, 753490)
>>> end = datetime.datetime(2020, 11, 6, 16, 36, 59, 753590)
>>> splits = end.day - start.day
>>> splits
1
I'm not 'in'-sane. Indeed, I am so far 'out' of sane that you appear a tiny blip on the distant coast of sanity. Bucky Katt, Get Fuzzy
Da Bishop: There's a dead bishop on the landing. I don't know who keeps bringing them in here. ....but society is to blame.
Posts: 414
Threads: 111
Joined: Apr 2020
TO perfringo, I did that just a little bit different way.
I can get time dif in days or just hours or seconds. It is the next, how to calculate exactly total hours per each day.
from datetime import datetime, date, time, timedelta
lsn = '2020-11-05 19:45:16'
fln = '2020-11-03 09:30:16'
fmt = '%Y-%m-%d %H:%M:%S'
tstamp1 = datetime.strptime(lsn, fmt)
tstamp2 = datetime.strptime(fln, fmt)
if tstamp1 > tstamp2:
td = tstamp1 - tstamp2
tdif = str(td)
print ("TIME Difference -----------",tdif)
td_mins = int(td.total_seconds() / 60)
print ("Time Dif in Minntes --- ", td_mins)
td_sec = int(round(td.total_seconds()))
print('The difference IN SEONDS ---------%s seconds' % td_sec)
Posts: 1,950
Threads: 8
Joined: Jun 2018
Then I would continue with my initial idea which is roughly such:
- find whether splits are needed (1 < days)
- if split needed:
- calculate midnights
- based on midnights calculate first and last day duration
- construct first and last day rows
- if split is larger than 1 (more than two days)
- all remaining (i.e not first or last) days duration is 24 hours;
- iterate pairwise over midnights and construct rows
- append row before last
- if split is not needed then return initial row
Following implementation of idea above assumes that input data is correct (no validation is made of duration; all data fields are separated with comma followed by space etc.). While writing this I observed that desired output from OP contains error.
This code should be refactored but in this form it expresses my idea good enough.
from datetime import datetime, timedelta
from itertools import tee
data = ['2020-11-02 16:53:14, 2020-11-03 08:41:47, 15:48:33, JP04TNNV0015EN, Bell_13, TT_Dev, TG LK A',
'2020-11-04 17:53:14, 2020-11-06 09:41:47, 39:48:33, JP04TNNV0015EN, Bell_13, TT_Dev, TG LK A']
def parse_row(row):
start, end, duration, rest = row.split(', ', maxsplit=3)
formatter = '%Y-%m-%d %H:%M:%S'
dt_start = datetime.strptime(start, formatter)
dt_end = datetime.strptime(end, formatter)
splits = (dt_end.date()- dt_start.date()).days
rows = []
if splits:
def make_midnight(x): return dt_start.replace(day=dt_start.day + x + 1, hour=0, minute=0, second=0)
midnights = [make_midnight(i) for i in range(splits)]
first_day_duration = f'{str(timedelta(seconds=(midnights[0] - dt_start).total_seconds())):0>8}'
last_day_duration = str(dt_end.time())
rows.append(', '.join([start, str(midnights[0]), first_day_duration, rest]))
rows.append(', '.join([str(midnights[-1]), end, last_day_duration, rest]))
if 1 < splits:
first, second = tee(midnights)
next(second, None)
for x, y in zip(first, second):
rows.insert(-1, ', '.join([str(x), str(y), '24:00:00', rest]))
else:
rows.append(row)
return rows
# usage
for row in data:
print(*parse_row(row), sep='\n')
2020-11-02 16:53:14, 2020-11-03 00:00:00, 07:06:46, JP04TNNV0015EN, Bell_13, TT_Dev, TG LK A
2020-11-03 00:00:00, 2020-11-03 08:41:47, 08:41:47, JP04TNNV0015EN, Bell_13, TT_Dev, TG LK A
2020-11-04 17:53:14, 2020-11-05 00:00:00, 06:06:46, JP04TNNV0015EN, Bell_13, TT_Dev, TG LK A
2020-11-05 00:00:00, 2020-11-06 00:00:00, 24:00:00, JP04TNNV0015EN, Bell_13, TT_Dev, TG LK A
2020-11-06 00:00:00, 2020-11-06 09:41:47, 09:41:47, JP04TNNV0015EN, Bell_13, TT_Dev, TG LK A
I'm not 'in'-sane. Indeed, I am so far 'out' of sane that you appear a tiny blip on the distant coast of sanity. Bucky Katt, Get Fuzzy
Da Bishop: There's a dead bishop on the landing. I don't know who keeps bringing them in here. ....but society is to blame.
Posts: 414
Threads: 111
Joined: Apr 2020
Well, the script is working! I could never do it myself. Thank you perfringo!
|