Add two ISO 8601 durations
Enter two ISO 8601 durations and get their sum as one clean duration: P1W plus P3D gives P10D, because weeks become seven days. Seconds, minutes, hours and months carry over, and zero units are dropped. Free in your browser.
- Free
- Runs in your browser
- No sign-up
- Your data stays on your device
Run — free
Worked example
- Duration1
- P1Y2M3DT4H5M6S
- Duration2
- P2Y1M10DT1H55M54S
- Sum
- P3Y3M13DT6H1M
- Years
- 3
- Months
- 3
- Days
- 13
ISO 8601 duration strings such as P1Y2M3DT4H5M6S appear in APIs, calendars, service-level agreements, and configuration files whenever a length of time must be written without anchoring to a calendar date. Adding two of those strings by hand is error-prone: weeks must become days, seconds must carry into minutes, and months must roll into years without inventing a day-to-month conversion that depends on a start date. This add-two-ISO-8601-durations calculator accepts two non-negative duration strings, parses each designator in fixed order, expands weeks into seven-day blocks, adds every component, and returns a single normalized duration plus the individual year, month, day, hour, minute, and second fields.
What ISO 8601 duration addition means
An ISO 8601 duration describes a length of time with the designators Y for years, M for months, W for weeks, D for days, and after a T marker H for hours, M for minutes, and S for seconds. Typical values include P1Y for one year, P2M15D for two months and fifteen days, PT1H30M for ninety minutes written as one hour thirty minutes, and the full form P1Y2M3DT4H5M6S. Adding two durations is a component-wise problem: years add to years, months to months, and so on.
Weeks are expanded into days using the fixed factor seven so that P1W plus P3D becomes P10D rather than a mixed week-and-day string. After addition the engine carry-normalizes time and month fields with deterministic integer rules: sixty seconds become one minute, sixty minutes become one hour, twenty-four hours become one day, and twelve months become one year. Days are never converted into months because month length depends on a calendar start date that this tool deliberately does not take.
The result is a canonical string that omits zero designators, uses P0D when every component is zero, and never emits a bare T with no time fields.
What to enter, what you get and what fails
Each value must be a non-negative ISO 8601 duration matching the ordered designator grammar PnYnMnWnDTnHnMnS with integer components only. On success the body echoes both inputs as canonical durations with weeks already expanded into days, the sum string after full carry normalization, the six non-negative integer component fields years, months, days, hours, minutes, and seconds, and a short formula reminder of the algorithm.
Example: duration1 equal to P1Y2M3DT4H5M6S and duration2 equal to P2Y1M10DT1H55M54S yield sum P3Y3M13DT6H1M because five minutes plus fifty-five minutes carry one hour, and six seconds plus fifty-four seconds stay under sixty. Rejected requests are not billed.
Where combining two ISO durations earns its keep
Product and platform teams combine lease periods, trial extensions, and maintenance windows that are already stored as ISO durations in configuration or billing systems; adding P1Y to P3M should yield P1Y3M without floating-point day approximations. Educators and documentation authors demonstrate duration arithmetic next to RFC and ISO tables without spreadsheet serial numbers that silently include times of day. Operations scripts merge backup retention windows or retry backoffs expressed as PnD and PTnH strings from two sources and write a single normalized value back to a registry.
Keep both strings small, pin the sum and component fields in tests, and you get reproducible duration addition for homework, LMS plugins, edge workers, and catalog landings that rank for add two ISO 8601 durations without standing up a full calendar library of your own.
What you can do with it
Billing and trial extensions
Add a base subscription duration to an extension window (for example P1Y plus P1M) and store the normalized sum back into configuration or invoices.
Merging retention and SLA windows
Combine two policy durations from different systems into one canonical PnYnMnDTnHnMnS string for registries and runbooks.
FAQ
How do I add two ISO 8601 duration strings?
Send duration1 and duration2 as non-negative PnYnMnWnDTnHnMnS strings.
Are weeks supported?
Yes. A W designator is accepted on input and converted to seven days before addition, so P1W plus P3D becomes P10D in the normalized sum.
Why are days not converted into months?
Month length depends on a calendar start date. This tool adds pure durations without a reference date, so days stay as days while months still carry into years at twelve.
Can I use negative or decimal values?
No. Each duration must be non-negative, with whole numbers in the standard order of designators. Plus or minus signs, fractions, a bare P and designators out of order are rejected instead of guessed.
Which units carry over after adding?
Sixty seconds become one minute, sixty minutes one hour, twenty-four hours one day and twelve months one year. For example, adding 5 minutes and 55 minutes carries one more hour into the hours.
Related tools
For developers — API access
Everything on this page is available programmatically. This section is for teams who want to wire it into their own systems; everyone else can just use the tool above.
API endpoint
Prefer to automate it? One authenticated POST creates the task; the result comes back by webhook or a signed link. The same capability also runs here on the web, by email and from Telegram — and soon from our app too.
Call it from your stack
curl -X POST https://api.kit.forhosting.com/date/iso-duration-add \
-H "Authorization: Bearer $KIT_KEY" \
-H "Content-Type: application/json" \
-d '{"duration1":"P1Y2M3DT4H5M6S","duration2":"P2Y1M10DT1H55M54S"}'const res = await fetch("https://api.kit.forhosting.com/date/iso-duration-add", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.KIT_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
"duration1": "P1Y2M3DT4H5M6S",
"duration2": "P2Y1M10DT1H55M54S"
})
});
const { task_id } = await res.json();import os, requests
res = requests.post(
"https://api.kit.forhosting.com/date/iso-duration-add",
headers={"Authorization": f"Bearer {os.environ['KIT_KEY']}"},
json={
"duration1": "P1Y2M3DT4H5M6S",
"duration2": "P2Y1M10DT1H55M54S"
},
)
task_id = res.json()["task_id"]<?php
$res = file_get_contents("https://api.kit.forhosting.com/date/iso-duration-add", false, stream_context_create([
"http" => [
"method" => "POST",
"header" => "Authorization: Bearer " . getenv("KIT_KEY") . "\r\nContent-Type: application/json",
"content" => '{"duration1":"P1Y2M3DT4H5M6S","duration2":"P2Y1M10DT1H55M54S"}',
],
]));
$task = json_decode($res, true);body := bytes.NewBufferString(`{"duration1":"P1Y2M3DT4H5M6S","duration2":"P2Y1M10DT1H55M54S"}`)
req, _ := http.NewRequest("POST", "https://api.kit.forhosting.com/date/iso-duration-add", body)
req.Header.Set("Authorization", "Bearer "+os.Getenv("KIT_KEY"))
req.Header.Set("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)Example request
{
"duration1": "P1Y2M3DT4H5M6S",
"duration2": "P2Y1M10DT1H55M54S"
}Example response
{
"task_id": "tsk_a1b2c3d4e5f6a1b2c3d4e5f6",
"type": "date.iso_duration_add",
"status": "queued",
"_links": {
"result": "/tasks/tsk_…/result"
}
}The API is asynchronous: the call returns a task_id immediately and the result arrives by webhook. Polling is capped at 1 req/s per task.
Pricing
Published price — no tokens, no invented credits. A failed task is never charged.
Errors
| HTTP | Code | Meaning |
|---|---|---|
401 | unauthorized | Missing or invalid API key. |
402 | insufficient_balance | Your balance doesn't cover the task price. |
404 | unknown_type | That task type doesn't exist. |
429 | rate_limited | Too many requests. Use the webhook instead of polling. |
Technical notes
What ISO 8601 duration addition means
That contract matches what validation libraries and schema forms expect when they check PnYnMnDTnHnMnS without re-parsing free text.
Input contract, response shape, and error behaviour
POST a JSON body with two required string fields: duration1 and duration2. Leading plus or minus signs are rejected so that the sum is always a non-negative length; empty strings, bare P, out-of-order designators, fractional parts, and non-duration text fail with invalid_input naming the field. Aliases a, first, left, and d1 map to duration1; b, second, right, and d2 map to duration2, so spreadsheets and query forms can reuse short column names. Pair the free browser run on this page with the priced API when you need the identical addition inside an automated pipeline without re-implementing duration parsers in every service.
Integration use cases
CI fixtures for schedulers
Assert that PT90M plus PT30M normalizes to PT2H in unit tests without depending on Date, locales, or the host clock.
Technical questions
What inputs are rejected?
Missing fields, empty strings, bare P, leading signs, fractional components, out-of-order designators, and non-duration text fail with invalid_input and are not billed.
What does the ISO duration adder cost?
The browser tool is free. API requests use prepaid KIT balance at $0.002 per successful call; invalid input is not billed.