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))