# Duration application check

`duration-application-check` · version 1.0.0 · Dates & times (UTC, ISO 8601) · free, no key needed

Check a claimed timestamp from adding or subtracting an ISO 8601 duration under explicit offset and month-end rules.

**Use when you need to: check timestamp plus iso duration result · verify date after adding P1M to january 31 · validate claimed end time of a duration.**

## Decide before calling

Read the [versioned contract](/v1/tools/duration-application-check/versions/1.0.0) and the supported scope below. Reuse `duration-application-check@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 `duration-application-check@1.0.0` for check timestamp plus iso duration result. 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

- check timestamp plus iso duration result
- verify date after adding P1M to january 31
- validate claimed end time of a duration
- did the agent subtract the duration correctly
- check month end clamping when adding months
- audit rfc 3339 timestamp plus period

## Not supported

- IANA time zones or daylight-saving transitions (fixed offsets only)
- leap seconds (second 60) and sub-nanosecond fractions
- fractional years, months, weeks or days
- business-day or holiday calendars

## Behavior

- Reference: ISO 8601-1:2019 durations with designators (years, months, weeks and days are nominal calendar units; hours, minutes and seconds are exact) and RFC 3339 section 5.6 date-time; reference_version is returned with every result.
- start and claim timestamps: RFC 3339 date-time YYYY-MM-DDTHH:MM:SS[.1-9 digits](Z|+HH:MM|-HH:MM), T and Z may be lower case, years 0000-9999 proleptic Gregorian; second 60 and more than 9 fractional digits are unsupported_input.
- duration: ISO 8601-1:2019 designator format; calendar components must be whole and the time part a whole number of nanoseconds (else unsupported_input).
- offset_policy (required): keep_start_offset does the calendar steps on the local date in the start offset and writes the result in that offset (-00:00 stays -00:00); utc does them on the UTC date and writes Z.
- Order of application: total months 12Y + M first (rollover policy on the local date), then 7W + D calendar days on the local date (time of day kept), giving calendar_result; then the exact time 10^9 (3600H + 60M + S) nanoseconds on the instant, giving result. direction subtract negates every component and keeps the same order.
- rollover (required): clamp moves a nonexistent day to the last day of the month (Jan 31 + P1M = Feb 28/29); overflow carries the excess days into the next month (Jan 31 + P1M = Mar 2/3); reject makes the claim invalid with reason day_overflow_rejected and invalid_local_date.
- Comparison order: claim.calendar_result (when given) then claim.result; each first by instant (difference_nanoseconds = claimed - actual), then by offset. A local date outside 0000-9999 gives reason result_out_of_range. actual is the canonical RFC 3339 text (uppercase T and Z, minimal fraction, Z for a zero offset).

## Input

- `start` (string, required): min length 20; max length 64
- `duration` (string, required): max length 100
- `direction` (one of "add", "subtract", required)
- `offset_policy` (one of "keep_start_offset", "utc", required)
- `rollover` (one of "clamp", "overflow", "reject", required)
- `claim` (object, required)

## Output

- `valid` (boolean, required)
- `reason` (one of null, "day_overflow_rejected", "result_out_of_range", "calendar_instant_mismatch", "calendar_offset_mismatch", "instant_mismatch", "offset_mismatch", required)
- `first_discrepancy` (object or null, required)
- `reference_version` (string, required)

## Limits

- max duration chars: 100
- max timestamp chars: 64

## Example

Request input:

```json
{
  "start": "2024-01-31T10:00:00Z",
  "duration": "P1M",
  "direction": "add",
  "offset_policy": "keep_start_offset",
  "rollover": "clamp",
  "claim": {
    "result": "2024-02-29T10:00:00Z"
  }
}
```

Response:

```json
{
  "result": {
    "valid": true,
    "reason": null,
    "first_discrepancy": null,
    "reference_version": "ISO 8601-1:2019 durations (designator format) + RFC 3339 (2002) timestamps; r66-duration-claim-verifiers@1.0.0"
  }
}
```

## How to call it

### MCP

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

```json
{
  "id": "duration-application-check",
  "version": "1.0.0",
  "input": {
    "start": "2024-01-31T10:00:00Z",
    "duration": "P1M",
    "direction": "add",
    "offset_policy": "keep_start_offset",
    "rollover": "clamp",
    "claim": {
      "result": "2024-02-29T10:00:00Z"
    }
  }
}
```

### HTTP (no key)

```sh
curl -X POST https://computefirst.net/v1/tools/duration-application-check/versions/1.0.0/execute \
  -H "Content-Type: application/json" \
  -d '{"start":"2024-01-31T10:00:00Z","duration":"P1M","direction":"add","offset_policy":"keep_start_offset","rollover":"clamp","claim":{"result":"2024-02-29T10:00:00Z"}}'
```

The machine-readable contract is at [/v1/tools/duration-application-check/versions/1.0.0](/v1/tools/duration-application-check/versions/1.0.0).

### CLI

```sh
node cli.mjs run duration-application-check 1.0.0 --input input.json --base-url https://computefirst.net
```

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

## Related tools

- [ISO duration structure check](/tools/iso-duration-structure-check): Check a claimed reading of an ISO 8601 duration: well-formedness, components and month/day/time totals.
- [ISO date month end](/tools/iso-date-month-end): Return the last valid calendar day of the year-month of a YYYY-MM-DD date.
- [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.
- [Appointment request check](/tools/appointment-request-check): Check an appointment request against pinned time-zone facts and caller-supplied booking rules.
- [ISO date add](/tools/iso-date-add): Add a signed whole-day delta to a strict YYYY-MM-DD calendar date.
- [ISO date add months](/tools/iso-date-add-months): Add a signed month count to a YYYY-MM-DD date, clamping the day to the target month.
