From 42db7078af67040a0eac52f28487a3b5ae8a7f16 Mon Sep 17 00:00:00 2001 From: YeonGyu-Kim Date: Mon, 11 May 2026 13:35:59 +0900 Subject: [PATCH] feat(boulder-state): add formatDurationHuman utility Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus --- .../boulder-state/format-duration.test.ts | 32 +++++++++++++++++++ src/features/boulder-state/format-duration.ts | 16 ++++++++++ src/features/boulder-state/index.ts | 1 + 3 files changed, 49 insertions(+) create mode 100644 src/features/boulder-state/format-duration.test.ts create mode 100644 src/features/boulder-state/format-duration.ts diff --git a/src/features/boulder-state/format-duration.test.ts b/src/features/boulder-state/format-duration.test.ts new file mode 100644 index 000000000..fbb9b30cb --- /dev/null +++ b/src/features/boulder-state/format-duration.test.ts @@ -0,0 +1,32 @@ +import { describe, expect, it } from "bun:test" +import { formatDurationHuman } from "./format-duration" + +describe("formatDurationHuman", () => { + it("returns 0s for 0ms", () => { + expect(formatDurationHuman(0)).toBe("0s") + }) + + it("returns 0s for 999ms", () => { + expect(formatDurationHuman(999)).toBe("0s") + }) + + it("returns 1s for 1000ms", () => { + expect(formatDurationHuman(1000)).toBe("1s") + }) + + it("returns 1m 0s for 60_000ms", () => { + expect(formatDurationHuman(60_000)).toBe("1m 0s") + }) + + it("returns 1h 0m 0s for 3_600_000ms", () => { + expect(formatDurationHuman(3_600_000)).toBe("1h 0m 0s") + }) + + it("returns 1h 2m 3s for 3_723_456ms", () => { + expect(formatDurationHuman(3_723_456)).toBe("1h 2m 3s") + }) + + it("returns 24h 0m 0s for 86_400_000ms", () => { + expect(formatDurationHuman(86_400_000)).toBe("24h 0m 0s") + }) +}) diff --git a/src/features/boulder-state/format-duration.ts b/src/features/boulder-state/format-duration.ts new file mode 100644 index 000000000..8065ddbd6 --- /dev/null +++ b/src/features/boulder-state/format-duration.ts @@ -0,0 +1,16 @@ +export function formatDurationHuman(milliseconds: number): string { + const totalSeconds = Math.max(0, Math.floor(milliseconds / 1000)) + const hours = Math.floor(totalSeconds / 3600) + const minutes = Math.floor((totalSeconds % 3600) / 60) + const seconds = totalSeconds % 60 + + if (hours > 0) { + return `${hours}h ${minutes}m ${seconds}s` + } + + if (minutes > 0) { + return `${minutes}m ${seconds}s` + } + + return `${seconds}s` +} diff --git a/src/features/boulder-state/index.ts b/src/features/boulder-state/index.ts index 17618996b..fec4b57de 100644 --- a/src/features/boulder-state/index.ts +++ b/src/features/boulder-state/index.ts @@ -2,3 +2,4 @@ export * from "./types" export * from "./constants" export * from "./storage" export * from "./top-level-task" +export * from "./format-duration"