Render a millisecond duration the same way ``formatDuration`` in ``typescript/src/utils/format.ts`` does.
(
ms: float,
*,
hide_trailing_zeros: bool = False,
most_significant_only: bool = False,
)
| 14 | |
| 15 | |
| 16 | def format_duration( |
| 17 | ms: float, |
| 18 | *, |
| 19 | hide_trailing_zeros: bool = False, |
| 20 | most_significant_only: bool = False, |
| 21 | ) -> str: |
| 22 | """Render a millisecond duration the same way ``formatDuration`` in |
| 23 | ``typescript/src/utils/format.ts`` does.""" |
| 24 | |
| 25 | if ms < 60_000: |
| 26 | if ms == 0: |
| 27 | return "0s" |
| 28 | if ms < 1: |
| 29 | return f"{ms / 1000:.1f}s" |
| 30 | return f"{int(math.floor(ms / 1000))}s" |
| 31 | |
| 32 | days = int(math.floor(ms / 86_400_000)) |
| 33 | hours = int(math.floor((ms % 86_400_000) / 3_600_000)) |
| 34 | minutes = int(math.floor((ms % 3_600_000) / 60_000)) |
| 35 | # Match JS ``Math.round`` (round-half-up) rather than Python's |
| 36 | # banker's rounding so 0.5s ticks land identically across the two |
| 37 | # implementations. |
| 38 | seconds = int(math.floor((ms % 60_000) / 1000 + 0.5)) |
| 39 | |
| 40 | # Carry rounded seconds (e.g. 59.5s → 60s → 1m). |
| 41 | if seconds == 60: |
| 42 | seconds = 0 |
| 43 | minutes += 1 |
| 44 | if minutes == 60: |
| 45 | minutes = 0 |
| 46 | hours += 1 |
| 47 | if hours == 24: |
| 48 | hours = 0 |
| 49 | days += 1 |
| 50 | |
| 51 | if most_significant_only: |
| 52 | if days > 0: |
| 53 | return f"{days}d" |
| 54 | if hours > 0: |
| 55 | return f"{hours}h" |
| 56 | if minutes > 0: |
| 57 | return f"{minutes}m" |
| 58 | return f"{seconds}s" |
| 59 | |
| 60 | hide = hide_trailing_zeros |
| 61 | |
| 62 | if days > 0: |
| 63 | if hide and hours == 0 and minutes == 0: |
| 64 | return f"{days}d" |
| 65 | if hide and minutes == 0: |
| 66 | return f"{days}d {hours}h" |
| 67 | return f"{days}d {hours}h {minutes}m" |
| 68 | if hours > 0: |
| 69 | if hide and minutes == 0 and seconds == 0: |
| 70 | return f"{hours}h" |
| 71 | if hide and seconds == 0: |
| 72 | return f"{hours}h {minutes}m" |
| 73 | return f"{hours}h {minutes}m {seconds}s" |
no outgoing calls