Duration Formatter Online — Milliseconds to Human-Readable Time

Convert millisecond values into six readable formats — short (3h 15m 22s), long, compact HH:MM:SS, ISO 8601 PT, days/hours, and words. Bulk mode handles lists, and Reverse mode parses strings back into milliseconds.

1d = 24h = 1,440m = 86,400s = 86,400,000ms
Tip: use modular arithmetic to break ms into days, h, m, s
Short
Long
Compact (HH:MM:SS)
ISO 8601
Days / Hours
Words
Enter a value to see all formats.

What is a duration formatter?

A duration formatter turns a raw integer (usually milliseconds) into a string a human can read at a glance: 11,722,000 ms becomes 3h 15m 22s. The opposite operation — taking 3h 15m and returning 11,700,000 — is parsing. Both are surprisingly absent from the JavaScript standard library, so engineers either pull in a 30 KB dependency or hand-roll the same modular arithmetic over and over.

This tool gives you all six common output formats from one input, plus a bulk mode for lists and a reverse mode for parsing back. Math is integer-only, so a value like 86_400_001 ms renders cleanly as 1d 0h 0m 0s with the trailing 1 ms intact instead of rounding to a decimal day.

How to format a duration online — 4 steps

  1. Pick a mode. Single (one value, six formats), Bulk (a list of ms, one per line), or Reverse (parse a human string into ms).
  2. Enter your value. Type or paste. In Single mode pick the unit so you can give days or hours instead of raw ms.
  3. Read every format side by side. Short, long, compact, ISO 8601, days/hours, and words update on every keystroke.
  4. Copy. Click any per-row copy icon, or use the toolbar Copy button to grab the whole table.

Sample input / output

Input: 11722000 ms

Short:    3h 15m 22s
Long:     3 hours 15 minutes 22 seconds
Compact:  03:15:22
ISO 8601: PT3H15M22S
Days/h:   0d 3h 15m 22s
Words:    three hours, fifteen minutes

Reverse: "3h 15m 22s" → 11722000 ms
Reverse: "PT3H15M22S" → 11722000 ms
Reverse: "01:15:22"   → 4522000 ms

Six formats at once

Short, long, compact HH:MM:SS, ISO 8601 PT, days/hours, and number-words from a single input field.

Bulk mode

Paste a column of millisecond values and the tool renders short / compact / ISO format for every row in one pass.

Reverse parsing

Type 3h 15m, PT3H15M, or 01:15:22 and get the equivalent millisecond integer for use in code.

Common use cases

  • check_circleFormatting request latency from APM tools (Datadog, New Relic) for status pages
  • check_circleConverting raw ms in JSON logs to readable spans for incident retros
  • check_circleBuilding "X hours ago" labels without pulling in moment.js
  • check_circleGenerating ISO 8601 PT strings for OpenAPI request_timeout fields
  • check_circleTranslating Cron expression intervals into "every 15m" UI labels
  • check_circleFilling Kubernetes activeDeadlineSeconds and Job ttlSecondsAfterFinished readably
  • check_circleProducing CSV exports with both raw ms and human-readable columns
  • check_circleParsing user-entered intervals like "2h 30m" in admin dashboards back to ms

Modular arithmetic vs date libraries

For pure time-of-day durations (no calendar context), modular arithmetic is faster, dependency-free, and exactly correct: const days = Math.floor(ms / 86_400_000); ms %= 86_400_000; and so on. Pulling in moment.duration() or dayjs.duration() costs ~30 KB gzipped to do the same math, with the upside of a fluent API and locale-aware output. For one-off labels in a server-rendered page, hand-rolled wins. For a dashboard with multiple locales, a library is worth it. ISO 8601 emit and parse are simple enough (one regex, one string concat) that the reach for a library is rarely justified.

Need other DateTime tools?

Pair the duration formatter with the rest of OpenFormatter's browser-side date and time toolkit.

Frequently Asked Questions

What is the ISO 8601 duration format?

ISO 8601 specifies durations as P[n]Y[n]M[n]DT[n]H[n]M[n]S — for example, PT3H15M22S means 3 hours, 15 minutes, and 22 seconds. The leading P stands for period; T separates date components from time components. Most APIs and standards (RFC 3339, OpenAPI, GitHub Actions schedule, Kubernetes resource lifetimes) use this format because it is unambiguous across locales and easily machine-parseable.

How do I format milliseconds to a readable string in JavaScript?

JavaScript has no built-in. The standard pattern is integer division: hours = Math.floor(ms / 3_600_000), then ms %= 3_600_000; minutes = Math.floor(ms / 60_000); and so on down to seconds and ms. Format with String(n).padStart(2, "0") for HH:MM:SS, or build a "3h 15m 22s" string by skipping zero parts. Libraries like dayjs (with the duration plugin), date-fns formatDuration, and humanize-duration wrap this for you.

What is the difference between Period and Duration?

In Java's java.time (and similar in C# / Joda-Time), Duration represents a time-based amount in seconds and nanoseconds — fixed length. Period represents a date-based amount in years/months/days — variable length because months and years differ. ISO 8601 covers both with one syntax (P1Y2M = period; PT3H = duration). This formatter focuses on duration; for variable-length intervals use the Date Difference Calculator.

How do I handle months and years (variable length)?

You cannot — a month is 28, 29, 30, or 31 days; a year is 365 or 366. Treating them as constants in millisecond math produces drift. The right pattern is to anchor calculations to a calendar (date-fns add/sub, Temporal.PlainDate.add). This formatter uses days as its largest unit, so a 1-year span shows as "365d" or "366d" — accurate, no rounding.

What is the right format for log timestamps?

For log line durations (request latency, job runtime), use compact short form like "327ms" or "3.2s" — humans skim it quickly. For structured fields in JSON logs, emit the raw integer milliseconds (e.g. duration_ms: 327) so log analytics tools can aggregate. ISO 8601 PT format is best for human-facing time spans in API responses (subscription_remaining: "PT720H").

How do I parse "PT3H15M" back to milliseconds?

A regex capture works: /^PT(?:(\d+)H)?(?:(\d+)M)?(?:(\d+(?:\.\d+)?)S)?$/i, then sum hours*3.6e6 + minutes*6e4 + seconds*1e3. The Reverse mode of this tool does exactly that, plus accepts looser strings like "3h 15m" and "01:15:22". For production code, the dayjs duration plugin or Java's Duration.parse(input) handles edge cases (negative, fractional seconds, weeks).

Should I display "1.5h" or "1h 30m"?

Decimal forms (1.5h, 0.25d) are best when the value will go into a chart, spreadsheet, or aggregation. Mixed forms (1h 30m, 6d 4h) are better for human reading because they avoid the cognitive load of converting fractions. UX rule of thumb: use decimal in dashboards, mixed in notifications. This tool emits both in the side-by-side panel so you can pick.

What about negative durations?

A negative duration means the end is before the start — common when computing time-until-deadline that has passed. The formatter accepts negative input and prefixes the output with a minus sign (e.g. -3h 15m, -PT3H15M). ISO 8601 strictly allows negation only on the whole duration with a leading minus, which is what we emit.

Duration Formatter — Milliseconds to Human-Readable