# Local interval normalize

`local-interval-normalize` · version 1.0.0 · Dates & times (UTC, ISO 8601) · free, no key needed

Normalize millisecond interval endpoint conventions into a canonical half-open interval.

**Use when you need to: normalize interval endpoints · convert closed interval to half open · canonicalize millisecond interval.**

## Decide before calling

Read the [versioned contract](/v1/tools/local-interval-normalize/versions/1.0.0) and the supported scope below. Reuse `local-interval-normalize@1.0.0` when your input, required output and limits match it. Choose another approach for an unsupported operation.

## Explain the choice

"I can use `local-interval-normalize@1.0.0` for normalize interval endpoints. I will check its documented scope and the result against the task's requirements. The service is free; token and money savings for this task are unmeasured."

## Supported

- normalize interval endpoints
- convert closed interval to half open
- canonicalize millisecond interval
- normalize inclusive end boundary
- normalize exclusive start boundary
- detect empty normalized interval

## Not supported

- generic date arithmetic
- resolve a local time zone
- continuous-number endpoint normalization

## Behavior

- Integer milliseconds form a discrete domain; ( adds one millisecond to start and ] adds one millisecond to end.
- Output is always the half-open interval [start_ms,end_ms).
- A normalized start after end is not_computable; equality is an empty interval.
- Caller endpoint rules are versioned by caller_rule_version.

## Input

- `start_ms` (string, required): min length 1; max length 32; pattern `^-?(?:0|[1-9]\d*)$`
- `end_ms` (string, required): min length 1; max length 32; pattern `^-?(?:0|[1-9]\d*)$`
- `endpoint_convention` (one of "[)", "[]", "()", "(]", required)
- `caller_rule_version` (string, required): min length 1; max length 64

## Output

- `standard_version` (string, required)
- `data_version` (string, required)
- `caller_rule_version` (string, required)
- `start_ms` (string, required)
- `end_ms` (string, required)
- `endpoint_convention` (constant "[)", required)
- `empty` (boolean, required)

## Limits

- max input bytes: 4096
- max integer chars: 32

## Example

Request input:

```json
{
  "start_ms": "10",
  "end_ms": "20",
  "endpoint_convention": "[]",
  "caller_rule_version": "r1"
}
```

Response:

```json
{
  "result": {
    "standard_version": "RFC9557/RFC3339/ISO8601-1:2019",
    "data_version": "iana-tzdb-2025b-subset-nyc",
    "caller_rule_version": "r1",
    "start_ms": "10",
    "end_ms": "21",
    "empty": false,
    "endpoint_convention": "[)"
  }
}
```

## How to call it

### MCP

Connect `https://computefirst.net/mcp` ([setup](/docs#connect)), then call `execute` with:

```json
{
  "id": "local-interval-normalize",
  "version": "1.0.0",
  "input": {
    "start_ms": "10",
    "end_ms": "20",
    "endpoint_convention": "[]",
    "caller_rule_version": "r1"
  }
}
```

### HTTP (no key)

```sh
curl -X POST https://computefirst.net/v1/tools/local-interval-normalize/versions/1.0.0/execute \
  -H "Content-Type: application/json" \
  -d '{"start_ms":"10","end_ms":"20","endpoint_convention":"[]","caller_rule_version":"r1"}'
```

The machine-readable contract is at [/v1/tools/local-interval-normalize/versions/1.0.0](/v1/tools/local-interval-normalize/versions/1.0.0).

### CLI

```sh
node cli.mjs run local-interval-normalize 1.0.0 --input input.json --base-url https://computefirst.net
```

Get the client at [/clients/cli/](/clients/cli/).

## Related tools

- [Local interval resolve](/tools/local-interval-resolve): Resolve a zoned local start/end pair to exact millisecond instants under explicit gap and overlap policies.
- [Local interval compare](/tools/local-interval-compare): Normalize and compare two discrete millisecond intervals with deterministic boundary relations.
- [Appointment windows build](/tools/appointment-windows-build): Build deterministic appointment windows from pinned time-zone facts and caller-supplied booking rules.
- [Duration application check](/tools/duration-application-check): Check a claimed timestamp from adding or subtracting an ISO 8601 duration under explicit offset and month-end rules.
- [ISO date quarter bounds](/tools/iso-date-quarter-bounds): Return the calendar quarter number and the first/last dates of the quarter containing a date.
- [ISO date to week](/tools/iso-date-to-week): Convert a YYYY-MM-DD calendar date to an ISO-8601 week date.
