Skip to content

Instantly share code, notes, and snippets.

@daverigby
Created November 15, 2023 14:33
Show Gist options
  • Save daverigby/1aa9b1c7ea2851bc75304849f2b4d4d0 to your computer and use it in GitHub Desktop.
Save daverigby/1aa9b1c7ea2851bc75304849f2b4d4d0 to your computer and use it in GitHub Desktop.
#!/usr/bin/env python3
"""Reads from stdin / arguments a sequence of lines which contain an
ISO 8601 timestamp, and outputs to stdout each line with the timestamp
with the delta from the previous line.
In other words, converts a file with absolute timstamps into a file
with relative timestamps since the previous line.
The first line cannot have a delta calculated, so it is reported as
zero.
"""
import datetime
import fileinput
import itertools
import re
ISO8601_REGEX = r"(.*?)(\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}.\d+[+-]\d{2}:\d{2})(.*)"
def parse_line(line):
m = re.search(ISO8601_REGEX, line)
if m:
dt = datetime.datetime.fromisoformat(m.group(2))
return (m.group(1), dt, m.group(3))
return None
# Are we processing the first line?
first_line = True
for lineA, lineB in itertools.pairwise(fileinput.input()):
parsedA = parse_line(lineA)
parsedB = parse_line(lineB)
if first_line:
# There is no previous line for the first line, so
# we cannot calculate a delta. Report a zero duration.
print("{}{}{}".format(parsedA[0], datetime.timedelta(), parsedA[2]))
first_line = False
continue
# If we found timestamps in both lines, calculate delta and print,
# otherwise just emit original line.
if parsedA and parsedB:
duration = parsedB[1] - parsedA[1]
print("{}{}{}".format(parsedB[0], duration, parsedB[2]))
else:
print(lineB, end=None)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment