API reference

Convert a time

Parse a date-time or Unix timestamp and show it in other zones and formats.

GET POST /api/time/convert MCP tool time_convert

Parses input and returns the instant in UTC, as Unix seconds and milliseconds, and in each zone of zones. The response says exactly how the input was read: the detected format, the inferred timestamp unit (with what the other units would have meant), and, for a wall-clock time without an offset, the zone used and whether that local time was unique, skipped by a DST gap, or repeated in a DST overlap.

Browser version (runs locally): Time & Time Zones.

Try it

Credentials
Remember these credentials

Not saved: you will paste them again next time.

No credentials yet? Get a client ID and secret. They are sent only to this site, in an Authorization: Basic header.

POST /api/time/convert with a JSON body

Parameters

Parameter Type Default Description
input required string (≤ 100 chars) — ISO 8601 / RFC 3339 (2026-10-13T14:30:00Z, 2026-10-13T14:30:00+02:00, 2026-10-13 14:30, 2026-10-13, 2026-W42-2, with an optional RFC 9557 [Zone/Name] suffix), RFC 2822, HTTP-date (IMF-fixdate, RFC 850, asctime), a Unix timestamp (seconds, milliseconds, microseconds or nanoseconds; decimals allowed), or now.
unit auto | seconds | milliseconds | microseconds | nanoseconds auto Unit of a numeric Unix timestamp. auto infers it from the magnitude: below 10^11 seconds, below 10^14 milliseconds, below 10^17 microseconds, otherwise nanoseconds. Only valid with numeric input.
from_zone string (≤ 64 chars) — Zone in which to read an input that has no UTC offset (2026-03-08T02:30). Required for such input; ignored when the input carries an offset or a Unix timestamp.
disambiguation compatible | earlier | later | reject compatible How to resolve a wall-clock time that falls in a DST gap or overlap (same meaning as in JavaScript Temporal). compatible: gap → shift forward by the gap length, overlap → earlier instant. earlier / later: pick that instant (in a gap, the instant before or after the gap). reject: fail with 422.
zones list of strings UTC Comma-separated (or JSON array) zones to show the instant in: IANA names, UTC, or fixed offsets such as +05:30. At most 20.
formats list of rfc2822 | http | sql | iso_basic | iso_week_date | iso_ordinal | human — Extra renderings added to each zone's formatted map: rfc2822 (Tue, 13 Oct 2026 14:30:00 +0200), http (HTTP-date, always GMT), sql (2026-10-13 14:30:00.000 +02:00), iso_basic (20261013T143000+0200), iso_week_date (2026-W42-2), iso_ordinal (2026-286), human (Tuesday, October 13, 2026 at 2:30:00 PM GMT+2).
pattern string (≤ 100 chars) — Custom format using Luxon tokens (e.g. yyyy-MM-dd HH:mm ZZZZ; quote literal text in single quotes). Added to formatted.pattern. English names.

Also accepted on every endpoint: format (json | text). Parameters may come from the query string, a JSON object body, an urlencoded or multipart form, or (for input) a text/plain body.

Global parameters
Parameter Type Default Description
format json | text json json returns the documented object. text returns only the primary value as text/plain (see "Text output").

Response 200 application/json

Field Type Description
input object
input.input string The input as received (trimmed).
input.format "now" | "iso8601" | "rfc2822" | "http-date" | "unix" How the input was parsed.
input.unit string | null Unit of a Unix timestamp (seconds, milliseconds, microseconds, nanoseconds); null for other formats.
input.unit_auto_detected boolean True when the timestamp unit was inferred from its magnitude.
input.has_offset boolean False when the input was a wall-clock time without a UTC offset, resolved in local_zone.
input.local_zone string | null Zone used to resolve a wall-clock input; null otherwise.
input.local_time string | null For wall-clock input: unique, gap (did not exist; DST jump forward) or overlap (occurred twice; DST jump back). Null otherwise.
input.notes array of string Every assumption made: auto-detected units and their alternatives, the zone used for wall-clock input, DST resolution, truncated precision.
instant object
instant.utc string The instant in UTC, ISO 8601 with Z.
instant.unix_seconds integer Whole seconds since 1970-01-01T00:00:00Z, rounded down (floor).
instant.unix_milliseconds integer Milliseconds since 1970-01-01T00:00:00Z.
zones array of object One entry per requested zone, in request order.
zones[].zone string Zone name as resolved: IANA name (letter case corrected), UTC, or UTC±HH:MM.
zones[].iso string ISO 8601 / RFC 3339 with the UTC offset (Z for UTC). Milliseconds appear only when non-zero.
zones[].local string Wall-clock date-time in the zone without an offset, YYYY-MM-DDTHH:mm:ss[.SSS].
zones[].date string Local calendar date, YYYY-MM-DD.
zones[].time string Local time, HH:mm:ss (24-hour), with .SSS only when milliseconds are non-zero.
zones[].offset string UTC offset, ±HH:MM.
zones[].offset_minutes integer UTC offset in minutes (east positive), e.g. -240 for UTC-04:00.
zones[].abbreviation string Short zone name as Intl (en-US) prints it: EDT, PST, or GMT+2 where English has no common abbreviation.
zones[].offset_name string Long zone name, e.g. Eastern Daylight Time.
zones[].dst boolean True when daylight saving time is in effect at this instant.
zones[].weekday string English weekday name, e.g. Tuesday.
zones[].weekday_number integer ISO 8601 weekday: 1 = Monday … 7 = Sunday.
zones[].iso_week string ISO 8601 week, YYYY-Www (the week-numbering year can differ from the calendar year near 1 January).
zones[].iso_week_year integer ISO 8601 week-numbering year.
zones[].iso_week_number integer ISO 8601 week number, 1-53.
zones[].day_of_year integer Ordinal day of the year, 1-366.
zones[].formatted map of string Extra renderings requested with formats (keyed by format name) and pattern (key pattern). Empty when none were requested.
warnings array of string Warnings about the zones given (fixed offsets, legacy or inverted names).

Text output (format=text, text/plain): The ISO 8601 time in each requested zone, one per line.

Errors

Errors are JSON: {"error": "<message>", "code": "<code>", "param": "<name>"?}.

Status Code When
400 invalid_parameter A zone is unknown or an abbreviation, or unit is given for non-numeric input.
422 unprocessable_input input is not a recognised format, is an impossible date (2026-02-30), is outside ±8.64e15 ms of 1970, has no offset and no from_zone, or falls in a DST gap/overlap with disambiguation=reject.
400 missing_parameter A required parameter is absent.
400 unknown_parameter A parameter name is not in the table above (typos are rejected, not ignored).
413 payload_too_large The request body exceeds 1 MiB.
405 method_not_allowed A method other than GET, POST or OPTIONS.

Behaviour

  • Idempotent: the same arguments always return the same result.
  • Requires a client ID and secret (authentication). Each call is recorded as one metadata row against your client ID; inputs and outputs are never stored or logged. Responses carry cache-control: no-store.
  • CORS: any origin may call this endpoint from a browser, using your credentials.

Examples

Responses below were produced by running each request through this code at build time. Long strings are shortened.

Unix timestamp (unit auto-detected) to two zones

curl 'https://util.caruana.me/api/time/convert?input=1791900000&zones=UTC%2CEurope%2FParis'

Response 200

{
  "input": {
    "input": "1791900000",
    "format": "unix",
    "unit": "seconds",
    "unit_auto_detected": true,
    "has_offset": true,
    "local_zone": null,
    "local_time": null,
    "notes": [
      "Unit auto-detected as seconds because the magnitude is below 10^11. For comparison, as milliseconds it would be 1970-01-… (90 more characters)"
    ]
  },
  "instant": {
    "utc": "2026-10-13T14:00:00Z",
    "unix_seconds": 1791900000,
    "unix_milliseconds": 1791900000000
  },
  "zones": [
    {
      "zone": "UTC",
      "iso": "2026-10-13T14:00:00Z",
      "local": "2026-10-13T14:00:00",
      "date": "2026-10-13",
      "time": "14:00:00",
      "offset": "+00:00",
      "offset_minutes": 0,
      "abbreviation": "UTC",
      "offset_name": "UTC",
      "dst": false,
      "weekday": "Tuesday",
      "weekday_number": 2,
      "iso_week": "2026-W42",
      "iso_week_year": 2026,
      "iso_week_number": 42,
      "day_of_year": 286,
      "formatted": {}
    },
    {
      "zone": "Europe/Paris",
      "iso": "2026-10-13T16:00:00+02:00",
      "local": "2026-10-13T16:00:00",
      "date": "2026-10-13",
      "time": "16:00:00",
      "offset": "+02:00",
      "offset_minutes": 120,
      "abbreviation": "GMT+2",
      "offset_name": "Central European Summer Time",
      "dst": true,
      "weekday": "Tuesday",
      "weekday_number": 2,
      "iso_week": "2026-W42",
      "iso_week_year": 2026,
      "iso_week_number": 42,
      "day_of_year": 286,
      "formatted": {}
    }
  ],
  "warnings": []
}
Same call as an MCP tools/call
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "time_convert",
    "arguments": {
      "input": "1791900000",
      "zones": [
        "UTC",
        "Europe/Paris"
      ]
    }
  }
}

Wall-clock time inside a DST gap

curl 'https://util.caruana.me/api/time/convert?input=2026-03-08T02%3A30&from_zone=America%2FNew_York&zones=UTC'

Response 200

{
  "input": {
    "input": "2026-03-08T02:30",
    "format": "iso8601",
    "unit": null,
    "unit_auto_detected": false,
    "has_offset": false,
    "local_zone": "America/New_York",
    "local_time": "gap",
    "notes": [
      "No offset in the input: read as wall-clock time in America/New_York (set by from_zone).",
      "2026-03-08T02:30:00 does not exist in America/New_York: it falls in a 60-minute DST gap. Resolved to 2026-03-08T03:30:00… (79 more characters)"
    ]
  },
  "instant": {
    "utc": "2026-03-08T07:30:00Z",
    "unix_seconds": 1772955000,
    "unix_milliseconds": 1772955000000
  },
  "zones": [
    {
      "zone": "UTC",
      "iso": "2026-03-08T07:30:00Z",
      "local": "2026-03-08T07:30:00",
      "date": "2026-03-08",
      "time": "07:30:00",
      "offset": "+00:00",
      "offset_minutes": 0,
      "abbreviation": "UTC",
      "offset_name": "UTC",
      "dst": false,
      "weekday": "Sunday",
      "weekday_number": 7,
      "iso_week": "2026-W10",
      "iso_week_year": 2026,
      "iso_week_number": 10,
      "day_of_year": 67,
      "formatted": {}
    }
  ],
  "warnings": []
}
Same call as an MCP tools/call
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "time_convert",
    "arguments": {
      "input": "2026-03-08T02:30",
      "from_zone": "America/New_York",
      "zones": [
        "UTC"
      ]
    }
  }
}

RFC 2822 to Tokyo, with extra formats

curl 'https://util.caruana.me/api/time/convert?input=Tue%2C%2013%20Oct%202026%2014%3A30%3A00%20%2B0200&zones=Asia%2FTokyo&formats=http%2Ciso_week_date%2Chuman'

Response 200

{
  "input": {
    "input": "Tue, 13 Oct 2026 14:30:00 +0200",
    "unit": null,
    "unit_auto_detected": false,
    "has_offset": true,
    "local_zone": null,
    "local_time": null,
    "notes": [],
    "format": "rfc2822"
  },
  "instant": {
    "utc": "2026-10-13T12:30:00Z",
    "unix_seconds": 1791894600,
    "unix_milliseconds": 1791894600000
  },
  "zones": [
    {
      "zone": "Asia/Tokyo",
      "iso": "2026-10-13T21:30:00+09:00",
      "local": "2026-10-13T21:30:00",
      "date": "2026-10-13",
      "time": "21:30:00",
      "offset": "+09:00",
      "offset_minutes": 540,
      "abbreviation": "GMT+9",
      "offset_name": "Japan Standard Time",
      "dst": false,
      "weekday": "Tuesday",
      "weekday_number": 2,
      "iso_week": "2026-W42",
      "iso_week_year": 2026,
      "iso_week_number": 42,
      "day_of_year": 286,
      "formatted": {
        "http": "Tue, 13 Oct 2026 12:30:00 GMT",
        "iso_week_date": "2026-W42-2",
        "human": "Tuesday, October 13, 2026 at 9:30:00 PM GMT+9"
      }
    }
  ],
  "warnings": []
}
Same call as an MCP tools/call
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "time_convert",
    "arguments": {
      "input": "Tue, 13 Oct 2026 14:30:00 +0200",
      "zones": [
        "Asia/Tokyo"
      ],
      "formats": [
        "http",
        "iso_week_date",
        "human"
      ]
    }
  }
}