قالببندی عدد و تاریخ
تقویم شمسی، جداکنندهٔ عدد و مقدار مختصر — کدام تابع برای کدام کار، و کدام تلهها واقعیاند
اصل
این فارسیترین کاری است که دیزاینسیستم انجام میدهد و تا امروز صفحه نداشت. دو قاعده کل ماجراست:
- رقم را تبدیل نکنید. ارقام فارسی از ویژگی
ss01فونت میآیند. جزئیات و اثباتش در فارسیمحور بودن. - قالب را تبدیل کنید. جداکنندهٔ هزار، مختصرسازی و تاریخ شمسی کارِ کد است، چون آنها شکل عدد نیستند، معنای آناند.
نمونه بصری
| فراخوانی | رشتهٔ خروجی | آنچه کاربر میبیند |
|---|---|---|
| formatNumber(1234567) | 1,234,567 | 1,234,567 |
| formatNumber(1234567, 'short') | 1.2M | 1.2M |
| formatLargeNumber(1234567, 'fa') | ۱.۲ میلیون | ۱.۲ میلیون |
| formatLargeNumber(1234567, 'en') | 1.2M | 1.2M |
| formatJalaliDate(date, 'yyyy/MM/dd') | 1405/05/05 | 1405/05/05 |
| getPersianMonthName(date) | مرداد | مرداد |
| getPersianWeekdayName(date) | دوشنبه | دوشنبه |
| formatPersianDateRange(from, to) | ۵ - ۹ مرداد ۱۴۰۵ | ۵ - ۹ مرداد ۱۴۰۵ |
ستون دوم و سوم یک رشتهاند. تفاوتشان کار فونت است: ویژگی ss01 گلیف ارقام لاتین را به فارسی نگاشت میکند، بدون آنکه codepoint عوض شود. به همین دلیل کپیکردن از ستون سوم، عددِ قابلاستفاده میدهد. دقت کنید که کاما در هیچ ستونی فارسی نمیشود — ss01 فقط ارقام را میگیرد.
قوانین اجباری
برای عدد، یکی از این دو تابع
import { formatNumber, formatLargeNumber } from '@partodata/ui'
formatNumber(1234567) // «1,234,567» — کدپوینت لاتین، فونت آن را «۱,۲۳۴,۵۶۷» نشان میدهد
formatLargeNumber(1234567, 'fa') // «۱.۲ میلیون» — پسوند فارسی
formatLargeNumber(1234567, 'en') // «1.2M» — برای رابط لاتینحالت `'short'` را در رابط فارسی به کار نبرید
خروجیاش پسوند لاتین دارد، و چون ss01 سراسری است کاربر رقم فارسی را با پسوند لاتین کنار هم
میبیند. برای مقدار مختصر در فارسی همیشه formatLargeNumber با locale فارسی. چراییاش با
اثبات، در فارسیمحور بودن.
جداکنندهها را فونت عوض نمیکند
ss01 فقط ده گلیف رقم را جانشین میکند — این با پارس مستقیم جدول GSUB سنجیده شده. کاما، نقطه،
% و ٪ دستنخورده میمانند. پس formatNumber(1234567) بهشکل «۱,۲۳۴,۵۶۷» دیده میشود، با کاماى
اسکی، نه جداکنندهٔ فارسی «٬». اگر جداکنندهٔ فارسی میخواهید باید صریحاً بنویسیدش؛ خودبهخود نمیآید.
برای تاریخ، از توابع شمسی — نه محاسبهٔ دستی
import {
formatJalaliDate,
getPersianMonthName,
formatPersianDateRange,
jalaliToGregorian,
} from '@partodata/ui'
formatJalaliDate(new Date(), 'yyyy/MM/dd')
getPersianMonthName(new Date()) // «مرداد»
formatPersianDateRange(from, to) // «۳ - ۷ مرداد ۱۴۰۵»
jalaliToGregorian(1405, 5, 3) // Dateپشت همهی اینها date-fns-jalali است، و این انتخاب قفل شده: moment-jalaali از ۲۰۱۹
بینگهدارنده است و یک قانون ESLint هر import از moment* را میبندد. جایگزینش نکنید.
موارد استفاده رایج
زمان نسبی
import { formatRelativeLocaleTime } from '@partodata/ui'
formatRelativeLocaleTime(post.createdAt, 'fa') // «۳ ساعت پیش»درصد و واحد
درصد را با نشانهٔ فارسی ٪ بنویسید، نه %. هیچکدام از این دو را فونت عوض نمیکند، پس انتخابش
دست شماست و باید در کل محصول یکدست باشد.
چه نکنیم
- تبدیل رقم در مسیر نمایش — نه با
toLocaleStringو locale فارسی، نه باconvertToLocalNumbers. هیچ سودی ندارد وCtrl+F، کپی به Excel، صفحهخوان و مرتبسازی را میشکند. toPersianDigitsبرای متن رابط. export شده و لازم است، ولی فقط برای مسیرهای غیرنمایشی: خروجی PDF، رندر روی canvas، یا عنصری کهfont-familyرا عوض میکند.- تکیه بر
PERSIAN_WEEKDAYSبا فرض ترتیب هفتهٔ فارسی. این آرایه به ترتیبgetDay()جاوااسکریپت است و با یکشنبه شروع میشود، نه شنبه. اگر با ایندکسِ روزِ فارسی سراغش بروید، روز اشتباه میگیرید. برای نام روز،getPersianWeekdayName(date)را صدا بزنید که خودش از localefaIRمیخواند و به این آرایه کاری ندارد. - انتظار ارقام همعرض. فونت یکان بخ ویژگی
tnumندارد و عرض ارقام فارسیاش از ۲۶۰ تا ۷۰۰ یونیت در یک em هزاریونیتی نوسان دارد.tabular-numsبیاثر است؛ اگر پایداری چیدمان لازم دارید، عرض ظرف را تثبیت کنید.
صفحات مرتبط
- فارسیمحور بودن — دکترین ارقام و اثبات
ss01 - تایپوگرافی — فونت یکان بخ و ویژگیهای OpenType آن
- انتخابگر بازهٔ تاریخ — همین توابع در یک کامپوننت واقعی