Hours difference between UTC offsets
This calculator finds the signed difference in hours between two fixed UTC offset strings.
Run — free
Enter a first offset and a second offset, and it subtracts the first from the second without consulting a clock, location, daylight-saving rule, or timezone database. The result is positive when the second offset is ahead of the first, negative when it is behind, and zero when both represent the same displacement from UTC. It also returns the exact difference in minutes for convenient downstream calculations.
Understand the direction of the signed result
The calculation follows one explicit order: second offset minus first offset. If offset A is UTC+02:00 and offset B is UTC+05:30, the result is +3.5 hours because B is three hours and thirty minutes farther east of UTC than A. Reversing those same inputs produces -3.5 hours. That sign is useful when a program needs to adjust a wall-clock value from the first fixed offset toward the second, but this capability deliberately does not accept or transform a date or time. It reports only the offset difference. A zero result means the two strings describe the same UTC displacement, even if one uses UTC and the other uses Z. The response includes normalized versions of both inputs, a decimal hour value, and an integer minute value. The minute value prevents ambiguity when an offset includes a half hour, quarter hour, or another valid minute component, while the hour value provides the direct answer most users need.
Enter fixed UTC offsets in a precise format
Use UTC followed by a sign, two hour digits, a colon, and two minute digits, such as UTC+05:30 or UTC-04:00. You may omit the UTC prefix and send +05:30 or -04:00. For zero, UTC and Z are accepted as concise equivalents. Whitespace around the whole string is ignored, while spaces inside the offset are rejected so malformed input cannot be silently reinterpreted. Hours must remain within the civil fixed-offset range from minus fourteen hours through plus fourteen hours. At either fourteen-hour boundary, the minute part must be 00, and every other minute part must be between 00 and 59. Requiring an explicit sign and colon keeps inputs reviewable and makes mistakes such as confusing +530 with +05:30 impossible. Returned offsets are normalized to UTC±HH:MM, so equivalent accepted forms produce a consistent machine-readable shape. Invalid values return an invalid-input error that identifies which field needs correction rather than producing a guessed result.
Know what fixed offsets can and cannot tell you
A fixed UTC offset is a numeric displacement, not a geographic timezone. This distinction matters because places can change offset with daylight-saving transitions, government decisions, or historical rules. For example, a city may use one offset in winter and another in summer, while an offset string alone contains no location or date from which to select the applicable rule. This capability therefore performs no timezone lookup and makes no claim about the current local time in a named place. That narrow scope is what makes the answer deterministic: identical strings always produce identical output, regardless of when or where the request runs. Use it for validating configuration, comparing offsets already chosen by another system, preparing schedule arithmetic when the applicable offsets are known, or testing integrations that exchange numeric offsets. If your problem starts with named zones such as Europe/London or America/New_York, resolve those zones for the relevant instant first, then pass the resulting fixed offsets here.
What you can do with it
Compare configured service offsets
Confirm the signed hour gap between two systems whose fixed UTC offsets are already known.
Check schedule arithmetic
Obtain the adjustment to apply when moving a wall-clock value from the first offset toward the second.
Test offset integrations
Use normalized offsets and exact difference minutes as stable fixtures for APIs, forms, and data pipelines.
FAQ
How is the sign chosen?
The calculator subtracts offset_a from offset_b. A positive result means the second offset is ahead; a negative result means it is behind.
Does this account for daylight saving time?
No. It compares fixed numeric offsets only and does not use dates, locations, or timezone rules.
Which input formats are accepted?
Use UTC±HH:MM or ±HH:MM. UTC and Z are also accepted for a zero offset.
Are half-hour and quarter-hour offsets supported?
Yes. Any valid minute component from 00 through 59 is supported within the overall ±14:00 range.
Why is difference_minutes returned?
Integer minutes preserve the exact calculation and are convenient for further arithmetic when the difference is fractional in hours.
What does an API request cost?
Each API request costs $0.002; the browser version can run locally without consulting external services.
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/offset-difference-hours \
-H "Authorization: Bearer $KIT_KEY" \
-H "Content-Type: application/json" \
-d '{"offset_a":"UTC+05:30","offset_b":"UTC-04:00"}'const res = await fetch("https://api.kit.forhosting.com/date/offset-difference-hours", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.KIT_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
"offset_a": "UTC+05:30",
"offset_b": "UTC-04:00"
})
});
const { task_id } = await res.json();import os, requests
res = requests.post(
"https://api.kit.forhosting.com/date/offset-difference-hours",
headers={"Authorization": f"Bearer {os.environ['KIT_KEY']}"},
json={
"offset_a": "UTC+05:30",
"offset_b": "UTC-04:00"
},
)
task_id = res.json()["task_id"]<?php
$res = file_get_contents("https://api.kit.forhosting.com/date/offset-difference-hours", false, stream_context_create([
"http" => [
"method" => "POST",
"header" => "Authorization: Bearer " . getenv("KIT_KEY") . "\r\nContent-Type: application/json",
"content" => '{"offset_a":"UTC+05:30","offset_b":"UTC-04:00"}',
],
]));
$task = json_decode($res, true);body := bytes.NewBufferString(`{"offset_a":"UTC+05:30","offset_b":"UTC-04:00"}`)
req, _ := http.NewRequest("POST", "https://api.kit.forhosting.com/date/offset-difference-hours", body)
req.Header.Set("Authorization", "Bearer "+os.Getenv("KIT_KEY"))
req.Header.Set("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)Example request
{
"offset_a": "UTC+05:30",
"offset_b": "UTC-04:00"
}Example response
{
"task_id": "tsk_a1b2c3d4e5f6a1b2c3d4e5f6",
"type": "date.offset_difference_hours",
"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. |