تقویم شمسی

jalali-calendarمهارت

هفته از شنبه شروع میشه، سال با نوروز، و ساعت تهران +۳:۳۰ بدون تغییر تابستانی. این مهارت به مدل میگه تاریخ را چطور ذخیره کنه، چطور نشان بده و تعطیلی‌ها را از کجا بیاره.

کی به کار می‌آد

  • تقویم، انتخاب تاریخ و بازه‌ی زمانی
  • گزارش و نمودار ماهانه
  • نوبت‌دهی و مهلت پرداخت
  • هر جا Date به کاربر نشان داده میشه

شرط فعال شدن (description)

Handle dates and times for Iranian users: the Jalali / Solar Hijri calendar (تقویم شمسی، هجری خورشیدی), Saturday-first weeks, Tehran time (+03:30, no DST), Persian month and weekday names, formatting, storage, ranges, reports and holidays. Use whenever a date, time, calendar, date picker, deadline, booking, report period or age appears in a Persian (Farsi) product, or the user says تاریخ شمسی، تقویم فارسی، jalali، شنبه، نوروز.

مدل با همین چند خط تصمیم می‌گیره مهارت را بخونه یا نه. اگر می‌خواید در موقعیت‌های دیگری هم فعال بشه، همین را عوض کنید.

Jalali calendar (تقویم شمسی)

Iran runs on the Solar Hijri (Jalali) calendar. Users think in it, laws and invoices use it, fiscal years follow it. Gregorian is for storage and APIs only. Getting this wrong is visible on every screen with a date.

1. The calendar in one table

MonthNameDays
1فروردین31
2اردیبهشت31
3خرداد31
4تیر31
5مرداد31
6شهریور31
7مهر30
8آبان30
9آذر30
10دی30
11بهمن30
12اسفند29, or 30 in a leap year
  • The year starts at Nowruz (نوروز), the March equinox, on 20 or 21 March.

  • Year 1405 began on 21 March 2026. As a sanity anchor: 20 September 2026 is ۲۹ شهریور ۱۴۰۵.

  • Leap years do not follow a simple % 4 rule; use a tested conversion algorithm (VibeFarsi ships lib/jalali.ts, dependency-free and verified). Do not implement leap logic from memory.

2. Week and weekend

  • The week starts on Saturday (شنبه). Calendars, date pickers, weekly charts and "this week" ranges all start on Saturday, never Monday.

  • Weekday order: شنبه، یکشنبه، دوشنبه، سه‌شنبه، چهارشنبه، پنجشنبه، جمعه.

  • Friday is the weekend. Many offices close Thursday afternoon or all day. "Business days" means Saturday–Wednesday (or Thursday, ask the user).

  • Intl locales for fa-IR already report Saturday as the first day; do not override it with a Monday-first library default.

3. Time zone

  • Iran is UTC+03:30 all year. Daylight saving was abolished; do not apply a summer offset.

  • IANA zone: Asia/Tehran. Store instants in UTC (ISO 8601) and convert to Asia/Tehran for display.

  • Half-hour offset means naive "round to the hour" logic breaks; always convert through the zone, never by adding hours.

4. Storage and transport

  • Database and API: ISO 8601 / Unix time, Gregorian, UTC. Never store a Jalali string as the source of truth.

  • Convert to Jalali at the edge (server render or client display).

  • If a Jalali date must travel (a filter param, a form field), send it as 1405-06-29 with Latin digits, and validate it with a converter round-trip.

  • Birth dates and contract dates entered in Jalali are converted once on input; keep the original Jalali string only for display audit if needed.

5. Display formats

ContextFormatExample
Short numericyyyy/mm/dd with Persian digits۱۴۰۵/۰۶/۲۹
Longday, month name, year۲۹ شهریور ۱۴۰۵
With weekdayweekday firstیکشنبه ۲۹ شهریور ۱۴۰۵
Time24-hour, Persian digits۱۴:۳۰
Date and timedate، ساعت time۲۹ شهریور ۱۴۰۵، ساعت ۱۴:۳۰
RelativePersian words«۲ ساعت پیش»، «دیروز»، «فردا»، «۳ روز دیگر»
Range«از … تا …»از ۱ مهر تا ۱۵ مهر ۱۴۰۵
Month label in chartsmonth name (+ year if it changes)مهر، آبان، آذر ۱۴۰۵
  • Persian digits everywhere the user reads; Latin digits in values.

  • Month names are never translated or transliterated; take them from a table.

  • Never show «Sep 20, 2026» to an Iranian user, even as a secondary line, unless the product is bilingual by design.

6. Using Intl correctly

Intl.DateTimeFormat with the Persian calendar is fine for labels:

1new Intl.DateTimeFormat("fa-IR-u-ca-persian", {2  dateStyle: "long",3  timeZone: "Asia/Tehran",4}).format(date); // «۲۹ شهریور ۱۴۰۵»56// Latin digits when you need them (inputs, logs):7new Intl.DateTimeFormat("fa-IR-u-ca-persian-nu-latn", { dateStyle: "short" }).format(date);

Limits: Intl formats but does not give you year/month/day integers for arithmetic, month grids or validation. For a date picker, ranges, "add one month", leap checks and age, use a converter (toJalali / toGregorian).

7. Date pickers and ranges

  • Grid starts on Saturday; header shows «مهر ۱۴۰۵»; navigation arrows flip in RTL (previous month points right, next points left).

  • Today, selected and disabled states are visible without color alone.

  • Range picker: start and end inclusive, «از تاریخ / تا تاریخ» labels, presets like «۷ روز گذشته»، «این ماه»، «ماه گذشته» computed in Jalali.

  • Typing is allowed with Persian or Latin digits and / or - separators; normalize before parsing.

  • Min/max and disabled days (Fridays, holidays) are data, not hard-coded.

8. Reports, fiscal periods, age

  • Monthly reports group by Jalali month, not Gregorian; quarterly = بهار، تابستان، پاییز، زمستان.

  • Fiscal year for most Iranian companies is the Jalali year (1 فروردین to 29/30 اسفند). Ask before assuming otherwise.

  • Age and durations: compute from the Gregorian instants, then say it in Persian: «۲۴ سال»، «۳ ماه و ۱۰ روز».

  • «سال ۱۴۰۵» in prose, «۱۴۰۵» in tables; never «۰۵».

9. Holidays

  • Fixed Jalali holidays exist (Nowruz 1–4 فروردین, 12 and 13 فروردین, 14 and 15 خرداد, 22 بهمن, 29 اسفند), but most public holidays are religious and follow the lunar calendar, so they move ~11 days earlier every year.

  • Never hard-code a full holiday list from memory. Load it from an official calendar source the user provides or an API, keyed by Gregorian date, and cache per year.

  • Mark holidays in the picker as data (disabled + a tooltip with the name).

10. Checklist

  1. Storage Gregorian/UTC; display Jalali via a converter.

  2. Week starts Saturday; Friday is the weekend.

  3. Asia/Tehran, +03:30, no DST.

  4. Persian digits and month names in every visible date.

  5. Formats from section 5; no English month names.

  6. Leap years from the algorithm, not % 4.

  7. Holidays from data, not memory.

نمونه

پرامپت: «تاریخ ثبت سفارش را نشان بده»

بدون مهارت

Sep 20, 2026 (Sunday)

با مهارت

یکشنبه ۲۹ شهریور ۱۴۰۵

نمونه برای نشان دادن جهت تغییره؛ خروجی واقعی به مدل و پرامپت شما بستگی داره.

نصب

  1. با CLI

    این دستور فایل را در .claude/skills/jalali-calendar/SKILL.md می‌نویسه. CLI به init نیاز نداره؛ فقط باید داخل پوشه‌ی پروژه باشید.

    $npx vibefarsi add jalali-calendar
  2. دستی

    محتوای تب SKILL.md را کپی کنید و در مسیر ابزار خودتون بگذارید:

    • Claude Code.claude/skills/jalali-calendar/SKILL.md برای همین پروژه، یا ~/.claude/skills/jalali-calendar/SKILL.md برای همه‌ی پروژه‌ها
    • Cursor.cursor/skills/jalali-calendar/SKILL.md
    • Codex.agents/skills/jalali-calendar/SKILL.md
    • بقیه‌ی ابزارهاهمان فایل را در پروژه بگذارید و یک خط به AGENTS.md اضافه کنید:For any Persian task, read .claude/skills/jalali-calendar/SKILL.md first.
    کپی کل فایلregistry json

می‌خواید همه‌ی قوانین را یک‌جا داشته باشید؟ قوانین فارسی برای CLAUDE.md خلاصه‌ی همه‌ی مهارت‌ها در یک صفحه‌ست و قوانین کرافت رابط طرف طراحی را پوشش میده. npx vibefarsi init هر دو را داخل پروژه می‌نویسه.