ISO 8601 Duration Converter
Read a duration string as parts and seconds — or build one from numbers.
Duration
What it means
Paste a duration like PT30M on the left, or fill in the numbers below it.
A string like PT30M arrives, and you need it in seconds
A provisioning API answers with "gracePeriod": "P30D". A session endpoint answers with "idleTimeout": "PT30M". Your scheduler wants an integer, so somebody has to translate. That shape is an ISO 8601 duration: a P to open, then number-and-letter pairs, and a T splitting the calendar half from the clock half. Paste one on the left and you get the pieces, a sentence in English, a seconds total, and the date it lands on.
The T is where the bugs come from. M means months before it and minutes after it, so P1M is one month and PT1M is one minute — a factor of roughly 43,800. Neither is a syntax error, so nothing in your stack objects. A retry window meant as one minute that quietly became one month looks exactly like "the retry never fired", and the config string is the last place anyone looks.
These turn up more often than the format's reputation suggests. The YouTube Data API reports video length as contentDetails.duration, so a four-minute clip is PT4M13S. XML Schema has xs:duration, which is why they fill SOAP payloads and enterprise message formats. Java reads them natively through Duration.parse for the clock half and Period.parse for the calendar half — a split that exists for the same reason this page gives two different totals. JavaScript now has them first-class in Temporal.Duration.
That caveat on the seconds figure is shown rather than hidden. PT2H30M is 9,000 seconds and always will be. P1M is not: February is 28 days, March is 31, and no arithmetic settles that without knowing which month you meant. A total containing years or months therefore rests on an assumption — 365 and 30 here — stated in grey under the number. Give it a start date and the estimate becomes exact: run P1Y2M10DT2H30M from 13 August 2026 and the two months it crosses are 61 real days rather than the 60 assumed, so it lands a full day later. Nothing you type leaves your browser.
Working through a duration
- Paste the string – Anything from
PT30MtoP1Y2M10DT2H30M. Results update as you type, and an unparseable string says why rather than leaving a blank pane. - Read the components table – Every designator is listed, with the two
Mrows labelled by which side of theTthey came from. Components the string left out are greyed rather than hidden. - Set the start date – The end date and exact span are computed from it with real calendar months. Quote this figure, not the seconds total, whenever the duration contains years or months.
- Or go the other way – Fill in the number fields under the editor and the canonical string appears in the input as you type —
Tin the right place, empty components dropped.
Nothing will ever tell you that you wrote P30M when you meant PT30M. Both parse, both validate against xs:duration, both survive a code review. The mistake surfaces weeks later as a job that never ran. When you write one by hand, say it aloud in the order the letters appear — "P, thirty months" against "P, T, thirty minutes" — and the wrong one stops sounding right.
One string, four different answers
A grace period from a SIM lifecycle record: a year, two months, ten days and two and a half hours. Note the two totals at the bottom, and why they disagree.
P1Y2M10DT2H30M
1 year, 2 months, 10 days, 2 hours, 30 minutes Total seconds 37,593,000 — assumes 365-day years, 30-day months Added to 2026-08-13 2027-10-23 02:30:00 UTC 436 days 02:30:00 · 37,679,400 seconds The two totals differ by 86,400 — exactly one day. The extra day is the one the 30-day month assumption loses somewhere between August and October.
When this comes up
An API gives you a duration and your code wants a number
Video length, a token lifetime, a poll interval. Clock-only strings such as PT15M convert exactly and you can use the seconds directly. Anything with a Y, or an M before the T, is a rough sizing at best — do that arithmetic against a real date, or against an epoch value in the timestamp converter.
Writing a duration into a config file by hand
Type what you mean into the number fields and copy the canonical string out, instead of composing it from memory at the point where one stray T decides whether a cleanup job runs every half hour or every two and a half years.
Reading xs:duration out of an XML payload
Enterprise message formats lean on xs:duration heavily, and it is rarely the field you were looking at when the bug appeared. Pull the document apart with XML to JSON, then bring the duration string here.
Checking that a retention window ends where you think
A subscriber record kept for P18M from signup is a compliance question with an exact answer, and it is not 18 × 30 days. From 13 August 2026 it runs to 13 February 2028 — nine days past where the naive figure puts it.
What this page does
- Parses every component — years, months, weeks, days, hours, minutes, seconds — and labels the two
Mdesignators by which side of theTthey sit on. - Shows the total in seconds and, when years or months forced an assumption, says so in a grey note rather than presenting an estimate as a fact.
- Adds the duration to a start date with real calendar months and real leap years, in UTC so the answer does not move with your time zone.
- Builds the canonical string from number fields as you type, and accepts a leading minus for a negative duration as well as decimals such as
PT1.5H.
Questions people actually ask
What is the difference between P1M and PT1M?
One month and one minute. The T marks where the date part ends and the time part begins, and M is reused on both sides. There is no other difference and no warning anywhere: both are well-formed, both pass validation, and a system handed the wrong one behaves perfectly while doing something roughly 43,800 times too slowly.
Why is the seconds total marked as an assumption?
Because a month has no fixed length. Converting P1M to seconds needs a number of days, and the honest answer is 28 to 31 depending on which month; a year is 365 or 366 for the same reason. This page uses 365 and 30, the common convention, and shows the exact figure from a real start date underneath. Hours, minutes and seconds carry no such caveat.
What does 31 January plus one month give me?
Here, 3 March — the month number goes up by one and the day overflows, which is what JavaScript's own date methods do. Plenty of other implementations clamp instead and land on 28 or 29 February; Temporal and Java's Period both clamp by default. Neither is wrong, because the standard defines the syntax and not what a month-end collision should do. Worth knowing which you are getting before a billing cycle depends on it.
Can I combine weeks with days and months?
Strict ISO 8601 says no — W is meant to stand alone, so P2W is fine and P1M2W3D is not. Most implementations accept the mix anyway, and so does the parser here: P1M2W3D is read as one month, two weeks and three days rather than rejected. Worth knowing before you emit such a string, since the reader at the other end may be stricter. To stay safe, fold weeks into days yourself — P2W is unambiguously P14D.
What about fractions and negative durations?
ISO 8601 allows a decimal on the smallest component present, so PT1.5H is legal while P1.5Y2M is not; a leading minus like -PT30M is a later extension rather than part of the original standard. This page takes both, plus a comma as the decimal separator, which the standard prefers and almost nobody writes. Assume whatever reads your string next is stricter than this page is.
Related tools
Specifications and references
- W3C XML Schema Part 2 — xs:duration – The lexical rules most enterprise systems validate against
- RFC 3339 Appendix A — ISO 8601 in ABNF – A readable grammar for the syntax, and what JSON Schema's duration format points at
- ISO 8601-1:2019 – The standard itself, for when a colleague wants the primary source