DateMint by Harlo

Turn "next Friday at 3pm", "in 2 weeks" or "Dec 25 to Jan 2" into exact ISO 8601 timestamps in any IANA time zone, DST-aware. Pull every date out of an email or ticket with character offsets, normalize mixed timestamps to UTC, or get the current time in a zone. Deterministic for a given reference time and stateless, with a REST API and an MCP server for AI agents.

Try it

TextResolved (local)DayPrecisionFlags

API

curl -s https://datemint.mike-tusa.workers.dev/v1/resolve -H 'content-type: application/json' \
  -d '{"text":"next Friday at 3pm","timezone":"America/Denver"}'

For AI agents

Models guess at dates. Call DateMint before acting on any date a user typed. Remote MCP server (Streamable HTTP, no auth needed for the free tier): https://datemint.mike-tusa.workers.dev/mcp. Tools: resolve_date, extract_dates, normalize_timestamps, current_time. Also llms.txt and OpenAPI 3.1.

{
  "mcpServers": {
    "datemint": {
      "type": "http",
      "url": "https://datemint.mike-tusa.workers.dev/mcp"
    }
  }
}

Plans

Honest limits

Rule-based parsing (chrono-node), not an AI model: it reads common date and time phrases and can miss or misread unusual wording, so check results before booking anything that matters. English (en, en-GB) is the most complete; other locales cover common phrases only. Numeric dates like 03/04/2026 are flagged ambiguous (en reads month/day, en-GB day/month). A date with no stated time gets an implied time (time_stated false). Time-zone abbreviations such as CST or IST are ambiguous; pass an IANA timezone instead. resolve reads its text whole; extract scans long text in overlapping pieces (240 characters plus 64 before and 96 after), so a date that crosses a piece boundary is read like any other, except one longer than about 96 characters, which may be split. Runs of more than 64 characters without spaces (URLs, hashes, tokens; Chinese and Japanese characters do not count), runs of more than 16 Chinese numerals, and the middle of a run of 7 or more standalone 1-2 digit numbers ("1 2 3 4 5 6 7"; the first and last 3 are still read) are skipped without changing the dates next to them, and a run of more than 8 spaces or line breaks ends a phrase. Extract returns at most max_results dates (default 20, maximum 25; larger values are rejected with HTTP 400) and stops once that many are found (truncated true, truncated_reason "max_results"). In number-dense text (tables, long lists of figures) it also stops scanning once roughly 600 numbers have been read (truncated true, truncated_reason "number_budget"): the dates it returns are correct, but dates later in the text are not returned, and raising max_results does not change that; send the rest of the text in a separate request. truncated_reason is null when truncated is false. Years 1900-2200. No holiday or business-day calendars. Stateless: text is not stored or logged; no URL fetching.