Overlapping time of two intervals calculator
This overlapping time calculator measures exactly how long two explicit datetime intervals share.
Run — free
Supply the start and end of each interval in ISO 8601 format, including either Z or a numeric UTC offset. The calculation converts every boundary to the same UTC timeline, finds the later start and earlier end, and reports the shared duration in milliseconds, seconds, minutes, and hours. Separate intervals and intervals that merely touch return zero, making the result straightforward to use in scheduling, billing, monitoring, and reporting workflows.
Define both intervals with unambiguous boundaries
Enter four values: the start and end of the first interval, followed by the start and end of the second. Every value must be a complete ISO 8601 datetime containing a calendar date, a clock time with seconds, and either Z or an explicit offset such as +02:00 or -05:30. Requiring an offset prevents a local wall-clock value from being interpreted differently on another computer. Each start must be earlier than its corresponding end. The calculator treats intervals as half-open ranges: the start belongs to the interval, while the end is its boundary. That convention avoids counting the same instant twice when adjacent bookings, shifts, or processing windows meet. Fractional seconds from one through three digits are accepted and normalized to milliseconds. Calendar dates and clock components are validated directly, so impossible values such as February 30, hour 25, or a malformed offset produce an input error instead of a plausible but incorrect duration. Use the same four fields whether the ranges are expected to overlap or not; no special flag is needed for empty intersections.
Understand the deterministic UTC calculation
The calculation places all four boundaries on one UTC timeline before comparing them. A value ending in Z is already in UTC. A value with a positive numeric offset is moved backward by that offset, while a value with a negative offset is moved forward. This means two differently written datetimes can represent the same instant. After conversion, the overlap begins at the later of the two starts and ends at the earlier of the two ends. If that end is later than the computed start, their difference is the overlap. Otherwise, the duration is exactly zero. The implementation uses Gregorian calendar arithmetic and integer millisecond values; it does not consult the machine clock, locale, timezone database, network, random data, or JavaScript Date behavior. Consequently, identical inputs always produce identical results. Output includes the same duration expressed as milliseconds, seconds, minutes, and hours. These are conversions of one computed quantity rather than separate rounded estimates, so consumers can choose the unit that best matches a database, invoice, dashboard, or scheduling rule.
Apply the result safely in real workflows
Use overlap duration whenever two known time windows must be compared: an employee shift against approved leave, equipment operation against a tariff period, an incident against a service window, or a reservation against an availability block. A positive value tells you how much shared time exists, not merely whether the intervals intersect. Zero has two possible meanings: the intervals are separated, or one ends at the exact instant the other begins. Both cases have no elapsed time in common under the half-open boundary convention. For money or quota calculations, prefer overlap_milliseconds or overlap_seconds as the source value and apply your own documented rounding only after receiving the result. Do not round each input boundary beforehand unless that is part of the business policy. The endpoint evaluates explicit offsets only; it does not accept named zones such as America/New_York and does not infer daylight-saving rules. Resolve named local times to ISO datetimes with offsets before calling it. The API costs $0.002 per request, while the browser implementation can run the same deterministic calculation locally for interactive checks.
What you can do with it
Measure shift coverage
Calculate how much of an employee shift falls inside a staffed, paid, or approved operating window.
Allocate incident time
Measure the portion of an outage that occurred during a contractual support or service-level period.
Check reservation conflicts
Quantify the shared time between two bookings instead of returning only a yes-or-no collision flag.
FAQ
What happens when the intervals do not overlap?
All four duration fields return zero. The same applies when one interval ends exactly when the other starts.
Are different UTC offsets supported?
Yes. Each boundary may use Z or its own explicit numeric offset, and all boundaries are compared on a common UTC timeline.
Are interval endpoints inclusive?
The calculation uses half-open intervals: each start is included and each end is excluded. This gives adjacent intervals zero shared duration.
Does the calculation use the server timezone?
No. It uses direct Gregorian and offset arithmetic without Date, a timezone database, the machine clock, or locale settings.
What does one API request cost?
The API price is $0.002 per request. Interactive browser execution is available without an API charge.
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/overlap-duration \
-H "Authorization: Bearer $KIT_KEY" \
-H "Content-Type: application/json" \
-d '{"first_start":"2026-07-25T09:00:00Z","first_end":"2026-07-25T12:30:00Z","second_start":"2026-07-25T11:15:00+00:00","second_end":"2026-07-25T14:00:00+00:00"}'const res = await fetch("https://api.kit.forhosting.com/date/overlap-duration", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.KIT_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
"first_start": "2026-07-25T09:00:00Z",
"first_end": "2026-07-25T12:30:00Z",
"second_start": "2026-07-25T11:15:00+00:00",
"second_end": "2026-07-25T14:00:00+00:00"
})
});
const { task_id } = await res.json();import os, requests
res = requests.post(
"https://api.kit.forhosting.com/date/overlap-duration",
headers={"Authorization": f"Bearer {os.environ['KIT_KEY']}"},
json={
"first_start": "2026-07-25T09:00:00Z",
"first_end": "2026-07-25T12:30:00Z",
"second_start": "2026-07-25T11:15:00+00:00",
"second_end": "2026-07-25T14:00:00+00:00"
},
)
task_id = res.json()["task_id"]<?php
$res = file_get_contents("https://api.kit.forhosting.com/date/overlap-duration", false, stream_context_create([
"http" => [
"method" => "POST",
"header" => "Authorization: Bearer " . getenv("KIT_KEY") . "\r\nContent-Type: application/json",
"content" => '{"first_start":"2026-07-25T09:00:00Z","first_end":"2026-07-25T12:30:00Z","second_start":"2026-07-25T11:15:00+00:00","second_end":"2026-07-25T14:00:00+00:00"}',
],
]));
$task = json_decode($res, true);body := bytes.NewBufferString(`{"first_start":"2026-07-25T09:00:00Z","first_end":"2026-07-25T12:30:00Z","second_start":"2026-07-25T11:15:00+00:00","second_end":"2026-07-25T14:00:00+00:00"}`)
req, _ := http.NewRequest("POST", "https://api.kit.forhosting.com/date/overlap-duration", body)
req.Header.Set("Authorization", "Bearer "+os.Getenv("KIT_KEY"))
req.Header.Set("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)Example request
{
"first_start": "2026-07-25T09:00:00Z",
"first_end": "2026-07-25T12:30:00Z",
"second_start": "2026-07-25T11:15:00+00:00",
"second_end": "2026-07-25T14:00:00+00:00"
}Example response
{
"task_id": "tsk_a1b2c3d4e5f6a1b2c3d4e5f6",
"type": "date.overlap_duration",
"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. |