Skip to content
    All updates

    Second-Precise UTC Offsets: ISO 8601 Input Now Accepts ±HH:MM:SS

    2026-10-27

    Before standard time zones, cities kept their own time. In tzdata, Paris ran 9 minutes and 21 seconds ahead of Greenwich until 1911, Monrovia ran 44 minutes and 30 seconds behind until 1972, and New York was at −4:56:02 until railway time arrived in 1883. These offsets have seconds in them.

    The TimeLogic API renders them exactly, and as of today it also accepts them as input. Anything that takes an ISO 8601 timestamp now understands ±HH:MM:SS offsets.

    Exact offsets out

    Ask for an instant in 1900 Paris:

    curl "https://api.timelogicapi.com/v1/time/convert?iso=1900-06-01T12:00:00Z&tz=Europe/Paris&format=%25z|%25:z" \
      -H "Authorization: Bearer $TIMELOGIC_API_KEY"
    
    {
      "unix": -2195899200,
      "unix_ms": -2195899200000,
      "utc": "1900-06-01T12:00:00Z",
      "iso_local": "1900-06-01T12:09:21+00:09:21",
      "rfc2822": "Fri, 01 Jun 1900 12:09:00 +0009",
      "human": "June 1, 1900, 12:09 PM Europe/Paris",
      "day_number": 6,
      "day_short": "Fri",
      "day_full": "Friday",
      "timezone": "Europe/Paris",
      "formatted": "+000921|+00:09:21"
    }
    
    • iso_local carries the full offset, +00:09:21, so the local time and the offset always describe the same instant.
    • format with %z gives +000921 and %:z gives +00:09:21.
    • rfc2822 can only express whole minutes, so it shows +0009 and the local time at the matching minute: 12:09:00.

    Exact offsets in: the round trip

    Now send that iso_local value straight back:

    curl -G "https://api.timelogicapi.com/v1/time/convert" \
      --data-urlencode "iso=1900-06-01T12:09:21+00:09:21" \
      --data-urlencode "tz=UTC" \
      -H "Authorization: Bearer $TIMELOGIC_API_KEY"
    
    {
      "unix": -2195899200,
      "utc": "1900-06-01T12:00:00Z",
      "iso_local": "1900-06-01T12:00:00+00:00",
      "timezone": "Etc/UTC"
    }
    

    (Response trimmed.) Same instant, to the second. Store iso_local, send it back later, and you land exactly where you started. That holds for any offset tzdata knows:

    Zone and date (12:00 UTC)iso_local
    Europe/Paris, 1900-06-011900-06-01T12:09:21+00:09:21
    Asia/Kolkata, 1900-06-011900-06-01T17:21:10+05:21:10
    Africa/Monrovia, 1960-06-011960-06-01T11:15:30-00:44:30
    America/New_York, 1880-06-011880-06-01T07:03:58-04:56:02

    Each of these goes back in as input and resolves to 12:00:00 UTC.

    A tip for query strings: + means a space in a URL. Use --data-urlencode as above, or write the plus sign as %2B (iso=1900-06-01T12:09:21%2B00:09:21).

    The offset is validated like the rest of the timestamp. Minutes or seconds of 60 or more (+00:09:61) return 400 INVALID_TIMESTAMP with "Invalid ISO timestamp.".

    offset_seconds next to offset_minutes

    The API supports local times from 0001-01-01T00:00:00 to 9999-12-31T23:59:59. When a conversion would land outside that range, the 400 INVALID_TIMESTAMP response tells you the zone and offset involved:

    curl "https://api.timelogicapi.com/v1/time/convert?iso=0001-01-01T03:00:00Z&tz=America/New_York" \
      -H "Authorization: Bearer $TIMELOGIC_API_KEY"
    
    {
      "error": {
        "code": "INVALID_TIMESTAMP",
        "message": "Local time in America/New_York falls outside years 0001-9999 (local year 0). Local results must stay between 0001-01-01T00:00:00 and 9999-12-31T23:59:59.",
        "details": {
          "local_year": 0,
          "timezone": "America/New_York",
          "offset_minutes": -296,
          "offset_seconds": -17762
        }
      },
      "request_id": "411b512a-ad5c-4408-9887-fcba63000ba9"
    }
    
    • offset_seconds is exact: −17762 s is −4:56:02.
    • offset_minutes is always a whole number, truncated toward zero (−296), the same rule rfc2822 uses.
    • offset_seconds appears only when the offset has seconds. A whole-minute offset, like Kiritimati's +14:00, reports "offset_minutes": 840 alone.

    Parse offset_minutes as an integer, and read offset_seconds when you need full precision.

    Who this is for

    • Genealogy, archives and historical datasets: timestamps from before standard time stay exact.
    • Data pipelines that store iso_local and replay it: no more rounding drift.
    • Anyone validating tz logic: compare your library's LMT output with the API to the second.

    See Selectors for every accepted iso shape, and the convert reference to try it.