Skip to content

Instantly share code, notes, and snippets.

@lsloan
Last active November 10, 2023 18:43
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save lsloan/e8fe3f50c2865703cfc58f318d7f85f5 to your computer and use it in GitHub Desktop.
Save lsloan/e8fe3f50c2865703cfc58f318d7f85f5 to your computer and use it in GitHub Desktop.
Two functions for creating a timestamp from a number of seconds. One from StackOverflow and mine. I thought I could do better.
def time_format(seconds: int) -> str:
"""
From: https://stackoverflow.com/a/68321739/543738
"""
if seconds is not None:
seconds = int(seconds)
d = seconds // (3600 * 24)
h = seconds // 3600 % 24
m = seconds % 3600 // 60
s = seconds % 3600 % 60
if d > 0:
return '{:02d}D {:02d}H {:02d}m {:02d}s'.format(d, h, m, s)
elif h > 0:
return '{:02d}H {:02d}m {:02d}s'.format(h, m, s)
elif m > 0:
return '{:02d}m {:02d}s'.format(m, s)
elif s > 0:
return '{:02d}s'.format(s)
return '-'
def periodFormatIso8601(seconds: int | float) -> str:
"""
My version of the above. I thought I could make it output
in ISO 8601 format and do it better. It needs a little more work.
P02D — no "T" if no time components
PT02H — use "T" if there are time components, even without date components
PT00S — always include seconds component if seconds is 0
PT00.143S — only include fractional seconds component when needed
"""
HOURS_PER_DAY = 24
MINUTES_PER_HOUR = 60
SECONDS_PER_MINUTE = 60
if seconds is None:
raise ValueError('seconds parameter cannot be None.')
if seconds < 0:
raise ValueError('seconds parameter cannot be negative.')
if seconds == 0:
return 'PT00S'
seconds, secondsFraction = divmod(seconds, 1)
seconds = int(seconds)
d = seconds // (HOURS_PER_DAY * MINUTES_PER_HOUR * SECONDS_PER_MINUTE)
h = seconds // (MINUTES_PER_HOUR * SECONDS_PER_MINUTE) % HOURS_PER_DAY
m = seconds % (MINUTES_PER_HOUR * SECONDS_PER_MINUTE) // MINUTES_PER_HOUR
s = seconds % (MINUTES_PER_HOUR * SECONDS_PER_MINUTE) % SECONDS_PER_MINUTE
formattedTime = (
(f'{d:02d}D' if d else '') +
('T' if h or m or s else '') +
(f'{h:02d}H' if h else '') +
(f'{m:02d}M' if m else ''))
sf = f'{secondsFraction:.3f}'[1:] if secondsFraction else ''
formattedTime += f'{s:02d}{sf}S' if s or sf else ''
return 'P' + formattedTime
def testFunctions(v, functions):
print(f'v: {v}')
for function in functions:
print(function(v))
print('- ' * 20)
for n in \
(
25 * 60 * 60 + 125,
17 * 60 * 60 + 35,
3500,
21,
0.25,
3600 + 1 / 7,
86400.25,
60,
0,
):
testFunctions(n, (time_format, periodFormatIso8601))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment