Skip to content

بین‌المللی‌سازی

sh
npm install @jalali-js/i18n

بیشتر برنامه‌ها این بسته را مستقیم وارد نمی‌کنند: useCalendar() و format() از قبل از طریق prop با نام locale در @jalali-js/react و @jalali-js/vue وصل شده‌اند. وقتی لازم است تاریخ را بیرون از مؤلفه قالب کنید، یا منطق نمایش خود را روی همان داده زبانی که آن رابط‌ها به کار می‌برند بسازید، مستقیم سراغ آن بروید.

format()

ts
import { format, en, fa, ps } from '@jalali-js/i18n';

const date = {
  precision: 'date' as const,
  system: 'jalali' as const,
  year: 1403,
  month: 5,
  day: 15,
};

format(date, en); // '15 Mordad 1403'
format(date, fa); // '۱۵ مرداد ۱۴۰۳'
format(date, ps); // '۱۵ زمری ۱۴۰۳' (نام ماه‌های افغانی؛ پایین را ببینید)
format(date, en, { style: 'short' }); // '15 Mor 1403'
format(date, en, { weekday: true }); // 'Monday, 15 Mordad 1403'
format(date, fa, { numerals: 'latin' }); // '15 مرداد 1403' (رقم لاتین، متن پارسی)

format() فقط برای نمایش است: نام ماه‌های خود date.system را می‌خواند (پس تاریخ با سامانه میلادی با نام ماه میلادی قالب می‌شود و تاریخ با سامانه جلالی با نام ماه جلالی، در هر زبانی)، و هرگز روی خروجی toStorageValue() اثر نمی‌گذارد. ببینید مقدار نمایش در برابر مقدار ذخیره.

formatRelative()

موقعیت from نسبت به to. انتخاب واحد از diffDates() در jalali-js استفاده می‌کند. رقم‌ها از numerals پیروی می‌کنند (پیش‌فرض: defaultNumerals زبان).

ts
import { formatRelative, en, fa, ps } from '@jalali-js/i18n';

const today = {
  precision: 'date' as const,
  system: 'jalali' as const,
  year: 1403,
  month: 5,
  day: 15,
};
const threeDaysAgo = { ...today, day: 12 };
const inTwoMonths = { ...today, month: 7 };

formatRelative(today, today, en); // 'today'
formatRelative(threeDaysAgo, today, en); // '3 days ago'
formatRelative(threeDaysAgo, today, fa); // '۳ روز پیش'
formatRelative(inTwoMonths, today, en); // 'in 2 months'
formatRelative(inTwoMonths, today, fa); // '۲ ماه بعد'
formatRelative({ ...today, day: 14 }, today, ps); // '۱ ورځ مخکې'
formatRelative(threeDaysAgo, today, fa, { numerals: 'latin' }); // '3 روز پیش'

هر دو تاریخ باید همان سامانه تقویم را داشته باشند.

قالب‌ها

وقتی شکل دقیق لازم دارید، یک template بدهید. جای چیدمان ازپیش‌تعیین‌شده را می‌گیرد، پس style و weekday نادیده گرفته می‌شوند. گزینه numerals همچنان اعمال می‌شود.

ts
format(date, en, { template: 'YYYY/MM/DD' }); // '1403/05/15'
format(date, fa, { template: 'YYYY/MM/DD' }); // '۱۴۰۳/۰۵/۱۵'
format(date, en, { template: 'D MMMM YYYY' }); // '15 Mordad 1403'
format(date, en, { template: 'dddd D MMM YYYY' }); // 'Monday 15 Mor 1403'
توکنمعنامثال
YYYYسال، ۴ رقم1403
MMماه، ۲ رقم05
Mماه5
DDروز، ۲ رقم15
Dروز15
MMMMنام ماه، بلندMordad
MMMنام ماه، کوتاهMor
ddddنام روز هفته، بلندMonday
dddنام روز هفته، کوتاهMon

متن بین توکن‌ها همان‌طور می‌گذرد. آن را به نشانه‌گذاری و فاصله محدود کنید: حرفی که با یک توکن هم‌خوان شود (برای مثال D در Day:) به‌عنوان آن توکن خوانده می‌شود.

parseTemplate()

برعکس قالب فرمت: خواندن سخت‌گیرانه یک شکل شناخته‌شده. ورودی آزاد به @jalali-js/nlp تعلق دارد.

ts
import { parseTemplate, en, fa } from '@jalali-js/i18n';

parseTemplate('1403/05/15', 'YYYY/MM/DD', en);
// { precision: 'date', system: 'jalali', year: 1403, month: 5, day: 15 }
parseTemplate('۱۴۰۳/۰۵/۱۵', 'YYYY/MM/DD', fa); // همان تاریخ؛ رقم بومی پذیرفته می‌شود
parseTemplate('15 Mordad 1403', 'D MMMM YYYY', en); // همان تاریخ
parseTemplate('2024/08/05', 'YYYY/MM/DD', en, { system: 'gregorian' });

به‌جای حدس زدن، null برمی‌گرداند:

  • ورودی باید دقیقاً با شکل قالب هم‌خوان باشد، بدون باقی‌مانده.
  • رقم‌ها می‌توانند لاتین یا مجموعه بومی زبان باشند.
  • تاریخ باید وجود داشته باشد: 1402/12/30 (۳۰ اسفند در سال غیرکبیسه) برابر null است.
  • نام روز هفته باید با تاریخ خوانده‌شده هم‌خوان باشد: 'Tuesday 15 Mordad 1403' برابر null است، چون آن روز دوشنبه است.
  • قالب باید سال، ماه و روز بسازد.

formatNumber()

قالب‌بندی رقمی که format() درون خودش به کار می‌برد، به‌تنهایی در دسترس است:

ts
import { formatNumber, fa } from '@jalali-js/i18n';

formatNumber(1403, 'native', fa.digits); // '۱۴۰۳'
formatNumber(1403, 'latin', fa.digits); // '1403'
formatNumber(5, 'latin', fa.digits, 2); // '05' (حداقل عرض اختیاری با صفر پر می‌شود)

بسته‌های زبان

en، fa و ps هر کدام یک LocalePack هستند: نام ماه برای هر دو سامانه تقویم (آوانویسی انگلیسی ماه‌های جلالی در en، آوانویسی پارسی ماه‌های میلادی در fa)، نام روز هفته، defaultNumerals، digits، direction متن، جایگاه‌نمای انتخابگر، و رشته‌های ظاهر ui برای aria-label کنترل‌ها. آن شیء ui برچسب‌های ناوبری را دارد (previousMonth، nextYear و مانند آن) و closedDay، برچسبی که انتخابگرها وقتی نوک راهنمای تعطیل روز را مسدود هم نشان می‌دهد اضافه می‌کنند (ببینید تعطیلات). فارسی شکل کوتاه استاندارد گسترده برای ماه مثل انگلیسی ندارد، پس نام ماه short در fa همان long را دوباره به کار می‌برد؛ نام روز هفته شکل کوتاه یک‌حرفی شناخته‌شده دارد، پس آن‌ها فرق می‌کنند. شکل کامل: LocalePack.

ps پشتو است، یکی از دو زبان رسمی افغانستان. افغانستان همان تقویم شمسی جلالی ایران را به کار می‌برد و ماه‌ها را از نشانه‌های زودیاک نام می‌گذارد. پس نام ماه‌های جلالی در ps (وری، غویی، ...، کب) نام‌های جایگزین همان ماه‌ها هستند و با نام‌های پارسی fa اشتراکی ندارند. داده از locale خود CLDR برای ps می‌آید، از طریق ICU، نه از حافظه. CLDR شکل کوتاه پشتو ندارد، پس سراسر short همان long را دوباره به کار می‌برد.

افزودن یک زبان

یک LocalePack داده ساده در برابر یک رابط صادرشده است. افزودن زبان کد دیگر این بسته را عوض نمی‌کند: format() هر بسته‌ای را که بدهید می‌خواند. گام‌ها، با ps به‌عنوان مثال کارشده:

  1. بسته را بنویسید. fa.ts (RTL) یا en.ts (LTR) را در packages/i18n/src/ کپی کنید و فیلدها را پر کنید: code، direction، ۱۰ نویسه digits، defaultNumerals، weekdaySeparator، نام ماه برای هر دو سامانه تقویم، نام روز هفته (شاخص ۰ یکشنبه است)، دو جایگاه‌نمای انتخابگر، رشته‌های ظاهر ui (یک کلید برای هر معنای کنترل، از جمله closedDay برای نوک راهنمای تعطیل مسدود)، و عبارت‌های relative (today، شکل‌های گذشته/آینده one/other با {n}). نام‌ها را از داده واقعی قابل تأیید بگیرید. CLDR از طریق Intl در Node خوب کار می‌کند: new Intl.DateTimeFormat('ps-AF-u-ca-persian', { month: 'long' }) نام ماه جلالی را می‌دهد، Intl.NumberFormat رقم‌ها را می‌دهد، و Intl.RelativeTimeFormat عبارت‌های نسبی را می‌دهد.
  2. آن را ثبت کنید. بسته را از packages/i18n/src/index.ts صادر کنید، و کد آن را به LocaleCode و جدول بسته در packages/i18n/src/locale-packs.ts اضافه کنید. همان یک جدول چیزی است که رابط‌های React، Vue و Web Components دوباره صادر می‌کنند، پس prop با نام locale کد تازه را بدون تغییر رابط می‌پذیرد.
  3. آزمون اضافه کنید که پوشش موجود fa در format.test.ts و numerals.test.ts را آینه کند: یک رشته قالب‌شده برای هر سبک، پیشوند روز هفته، و بازنویسی صریح numerals: 'latin'.
  4. اختیاری: عبارت‌های NLP. یک فهرست واژه در packages/nlp/src/word-list.ts خواندن زبان طبیعی برای آن زبان را اضافه می‌کند. این از بسته نمایش جدا است و فقط وقتی مجموعه عبارت خوب شناخته شود ارسال می‌شود. Intl.RelativeTimeFormat منبع قابل تأیید برای اصطلاحات نسبی است.