Persian Numbers, Currency & Dates

Persian interfaces have three recurring conventions that trip up otherwise-fine codebases: Persian digits, grouped currency, and Shamsi dates. This page points you at the components and utilities that handle each, and shows how they fit together.

1. Digits — ۰-۹, not 0-9

Users type and expect Persian digits. Normalize input and Persianify output with the same primitives the inputs use internally.

NeedTool
Convert Persian/Arabic-Indic to LatinNormalize Persian Digits
Convert to PersiantoPersianDigits from Persian Date
Read free-form user inputMobile Number Input, National ID Input normalize as you type

2. Currency — Toman and grouped prices

Toman is the everyday currency unit in Iran. The library ships a dedicated icon and a live-formatting price input.

NeedTool
The Toman symbolToman Icon
Live-grouped price input (۱٬۲۳۴٬۵۶۷)Price Input
Spell an amount for cheques/invoicesNumber to Persian Words (فقط دو میلیون و پانصد هزار تومان)

A common amount flow, end to end:

<PriceInput value={amount} onValueChange={setAmount} suffix={<TomanIcon />} />

3. Shamsi dates

The Jalali calendar is the default for Persian products. Everything date-related is Shamsi/Jalali-aware and switchable.

NeedTool
A date picker (Shamsi or Gregorian)Date Picker, Date Wheel Picker
Date math, formatting, conversionPersian Date
Validate dates in a schemaPersian Date (Zod)
Know if a day is a holidayPersian Holidays
Relative time ("۲ روز پیش")useTimeAgo

Example — format today and flag a holiday:

import { formatDate, isHoliday } from "@/lib/persian-date"

4. Putting it together

A typical checkout total, RTL, with Persian digits, Toman, and a Shamsi date stamp uses pieces from the sections above — the components share the same digit and date primitives, so the output stays consistent everywhere in your app.

Next steps

  • Theming — tune the color tokens these components read.
  • FAQ — common gotchas around digits, dates, and RTL.