No upload, 100% local, no account

Article

ISO 8601 durations: what P1DT2H means

A YouTube API response says a video lasts PT4M13S. A calendar invite carries P15DT5H0M20S. A directory server timestamps an account with 20260424174227.0Z, which looks related but is something else entirely. These compact strings follow rules worth knowing, because reading them wrong flips minutes into months. This is a tour of the ISO 8601 duration format: what the letters mean, where the format appears, and its one big subtlety, that a duration written this way is not always a fixed amount of time.

P, T, and what the letters mean

An ISO 8601 duration starts with P (period). Then come date components, each a number followed by its unit letter: Y years, M months, W weeks, D days. A T separates the date part from the time part: H hours, M minutes, S seconds. Every component is optional; you write only what you need. PT15M is 15 minutes, P1DT2H is one day and two hours, P3W is three weeks. The T is not decoration: M means months before it and minutes after it, so P1M is one month while PT1M is one minute. The last component present may carry a decimal fraction, as in PT0.5S for half a second. And the units do not roll over on their own: PT90M is a perfectly valid way to write an hour and a half.

Anatomy of the ISO 8601 duration P3Y6M4DT12H30M5S: P starts the period, Y M D are date units, T switches to time, H M S are time units

Where you actually meet the format

This syntax is quietly everywhere. The YouTube Data API reports every video length as an ISO 8601 duration (PT4M13S). HTML accepts durations in the datetime attribute of the time element. Calendar invites use it: the iCalendar standard (RFC 5545) writes event lengths like PT1H0M0S, though it drops years and months from the grammar. XML Schema's xs:duration covers the full form and even allows a leading minus for negative durations. Standard libraries parse it directly: java.time reads P and T strings with Period.parse and Duration.parse, and the same split exists in many other languages. If you produce machine-readable schedules, feeds or APIs, this format is the lingua franca for "how long".

Why P1M is not a fixed number of seconds

PT15M is always 900 seconds. P1M is not: a month lasts 28, 29, 30 or 31 days depending on where it starts, so P1M only becomes concrete once you anchor it to a date. Even P1D is not guaranteed to be 24 hours. In the European Union, clocks spring forward on Sunday 29 March 2026, so that calendar day lasts 23 hours: adding P1D (one calendar day) and adding PT24H (exactly 24 hours) to the same Saturday evening land on different instants. This is why java.time has two types, Period for calendar units and Duration for exact seconds, and why date libraries ask for a reference date before converting a duration. Treat Y, M, W and D components as calendar arithmetic, and only H, M and S as fixed amounts of time.

Not a duration: 20260424174227.0Z

A string like 20260424174227.0Z looks like it might belong to the same family, but it is a timestamp, not a duration, and not ISO 8601 either. It is GeneralizedTime, a format from ASN.1, the notation used by LDAP directories and X.509 certificates. Read it as fixed-width fields: year 2026, month 04, day 24, then 17:42:27, an optional fraction (.0), and Z for UTC. You meet it in Active Directory attributes such as whenCreated and whenChanged, in LDAP exports, and inside certificates, where RFC 5280 mandates GeneralizedTime for validity dates from the year 2050 on. The giveaway that distinguishes it from ISO 8601's compact form is the missing T: ISO would write the same instant as 20260424T174227Z.

The GeneralizedTime string 20260424174227.0Z decoded field by field into 24 April 2026, 17:42:27 UTC

Decoding one without reading the spec

For a one-off string, our ISO duration converter parses any P/T duration into its components and its total in seconds, and builds the string back from numbers you type. When what you have is two clock times rather than a duration string (a shift that ran from 22:00 to 06:30, say), the time duration calculator gives the elapsed time, overnight spans included. Both run entirely in your browser: nothing you type leaves your device. And for quick reading without any tool, two reflexes cover most cases: find the T to know whether an M means months or minutes, and remember that anything left of the T is calendar arithmetic, not a fixed number of seconds.

Tools in this article

Frequently asked questions

Is PT1M the same as P1M?

No. The letter M changes meaning across the T separator: P1M is one month, PT1M is one minute. This is the single most common misreading of the format, and API bugs have shipped because of it. When in doubt, scan for the T first: everything before it counts in years, months, weeks and days; everything after it counts in hours, minutes and seconds. A well-formed duration never has time units before the T or date units after it.

How do I write 90 minutes as an ISO 8601 duration?

PT90M and PT1H30M are both valid and describe the same amount of time. ISO 8601 does not force components into their conventional ranges, so minutes above 59 or hours above 23 are fine. Parsers accept either spelling; which one a system emits depends on whether it normalizes. If you generate durations for humans to read, PT1H30M is kinder; if you compare durations in code, compare their total seconds rather than their strings, precisely because two different strings can mean the same thing.

What is the difference between a duration and an interval?

A duration says how long, with no position on the calendar: P3D is three days, starting anywhere. An ISO 8601 interval pins a duration to actual dates, written with a slash: 2026-07-04T00:00:00Z/P3D means the three days starting 4 July 2026, and a start/end pair like 2026-07-04/2026-07-07 expresses the same span. There are also repeating intervals with an R prefix: R5/2026-07-04T00:00:00Z/P1D means five daily repetitions from that start. Intervals resolve the ambiguity of calendar units, since P1M anchored to a date always has one definite length.

Sources