---
title: "Calendar converter: Gregorian to Hijri, Hebrew, Japanese era, Persian and more, plus Easter date"
method: GET
path: "/v1/time/calendar"
tags: ["deterministic", "no-api-key", "time", "calendar"]
---

# Calendar converter: Gregorian to Hijri, Hebrew, Japanese era, Persian and more, plus Easter date

`GET /v1/time/calendar`

## Request

- Base URL: `https://api.duoleads.com`
- URL: `https://api.duoleads.com/v1/time/calendar`
- Auth: none declared

Calendar converter: convert a Gregorian date to other calendar systems: Islamic (both the tabular civil calendar and the Umm al-Qura variant), Hebrew, Japanese imperial era, Republic of China, Buddhist and Persian. Also computes Easter Sunday for a year in both the Gregorian and Julian reckonings. Uses the calendar support built into the runtime, with the algorithm named in every response.

**Output (`data`):** convert: gregorian, calendars {<id>: {year, month, month_name, day, era, formatted, algorithm}}, and unavailable {<id>: reason} when no to was given and a calendar is undefined for the date. Gregorian input covers years 1-9999 (proleptic Gregorian, so month and month_name always agree with the date given); every field is computed for the whole range, never clamped. A calendar that is undefined for the date is rejected with 400 INVALID_PARAM on date when named in to, and listed in unavailable when to is omitted: japanese before Meiji 1 (1868-10-23) and islamic-umalqura outside its published table (1300-1600 AH, 1882-11-12 to 2174-11-25). islamic and persian are proleptic before their epoch (year 0 and negative years, as ICU computes them). easter: year, rite, date (always the Gregorian date), gregorian_date, julian_date (eastern rite only: the date in the Julian calendar), algorithm (anonymous-gregorian|meeus-julian). islamic is the tabular civil calendar; Hebrew months are numbered from Tishri = 1.

Deterministic: identical input returns identical output, so the response is served with `Cache-Control: private, max-age=31536000, immutable` (the paying client may cache it indefinitely; shared caches must not, because the response is paid).

Price: $0.05 USDC per call (x402, Base). Route contract version 1.0.0. Docs: https://api.duoleads.com/docs#time-calendar

## Query parameters

- `op` 'convert' | 'easter'
- `date` string, date
- `to` string
- `year` integer
- `rite` 'western' | 'eastern'

## Response `200`

Paid and settled. `data` is route-specific; a route that judges its input returns 200 with `data.valid: false` for a bad value.

- object
  - `ok` unknown, required
  - `route` '/v1/time/calendar', required
  - `version` '1.0.0', required
  - `data` object, required: convert: gregorian, calendars {<id>: {year, month, month_name, day, era, formatted, algorithm}}, and unavailable {<id>: reason} when no to was given and a calendar is undefined for the date. Gregorian input covers years 1-9999 (proleptic Gregorian, so month and month_name always agree with the date given); every field is computed for the whole range, never clamped. A calendar that is undefined for the date is rejected with 400 INVALID_PARAM on date when named in to, and listed in unavailable when to is omitted: japanese before Meiji 1 (1868-10-23) and islamic-umalqura outside its published table (1300-1600 AH, 1882-11-12 to 2174-11-25). islamic and persian are proleptic before their epoch (year 0 and negative years, as ICU computes them). easter: year, rite, date (always the Gregorian date), gregorian_date, julian_date (eastern rite only: the date in the Julian calendar), algorithm (anonymous-gregorian|meeus-julian). islamic is the tabular civil calendar; Hebrew months are numbered from Tishri = 1.
    - `gregorian` string
    - `calendars` object: keyed by caller-chosen names
    - `year` integer
    - `rite` string
    - `date` string
    - `gregorian_date` string
    - `algorithm` string
    - `julian_date` string
    - `unavailable` object: keyed by caller-chosen names
  - `meta` Meta, required
    - `disclaimer` string, required: Legal short disclaimer, identical on every response.
    - `request_id` string, required: ULID.
    - `computed_at` string, date-time, required: RFC 3339 UTC with milliseconds.
    - `price_usd` string, required: Decimal string, "0.05".
    - `deterministic` boolean, required
    - `sources` object[]: Present only on routes that read a vendored dataset: the exact edition that answered.
      - `id` string, required
      - `version` string, required
      - `published` string, required
      - `attribution` string
      - `licence` string

## Other responses

- `400`: MISSING_PARAM, INVALID_PARAM or UNSUPPORTED_VALUE. Not charged: validation runs before the paywall.
- `402`: Payment required. No valid PAYMENT-SIGNATURE was supplied: read the base64 PAYMENT-REQUIRED header (or this body) for the price ($0.05 = 50000 atomic USDC on eip155:8453), sign an EIP-3009 authorization and retry. Also returned when settlement is declined (PAYMENT_FAILED). Nothing is charged on a 402.
- `404`: NOT_FOUND: unknown path. Not charged.
- `405`: METHOD_NOT_ALLOWED: only GET and HEAD are served. Not charged.
- `413`: INPUT_TOO_LARGE: a parameter exceeded its documented maximum length. Not charged.
- `500`: INTERNAL: a server bug. Not charged.

---

[API](https://skmtc.dev/duoleads/apis/duo-data-utilities-iban-isin-vat-tax-id-barcode-timezone-geo.md) · [All operations](https://skmtc.dev/duoleads/apis/duo-data-utilities-iban-isin-vat-tax-id-barcode-timezone-geo/llms.txt) · [OpenAPI document](https://skmtc.dev/duoleads/apis/duo-data-utilities-iban-isin-vat-tax-id-barcode-timezone-geo/revisions/18790d59615e?raw)
