مفهوم لوکال (Locale) زیربنای تمام رفتارها و قابلیتهای شیء Intl است. یک لوکال در واقع مجموعهای از قراردادها و قوانین فرهنگی و جغرافیایی است که در APIهای Intl با شیء Intl.Locale نشان داده میشود. تمام متدهای سازندهی مجموعه Intl که برچسبهای زبان را میپذیرند، شیء Intl.Locale را هم به عنوان ورودی قبول میکنند.
هر لوکال به طور کلی و در درجه اول توسط ۴ جزء تعریف میشود: یک زبان (Language)، یک خط نگارشی (Script)، یک منطقه/کشور (Region)، و گاهی اوقات برخی گویشها یا گونهها (Variants). وقتی این اجزاء به همین ترتیب با خط تیره (-) به هم متصل میشوند، یک برچسب زبان استاندارد (BCP 47 language tag) را تشکیل میدهند:
زبان (Language): مهمترین و اجباریترین بخش یک لوکال است. وقتی شما فقط یک زبان واحد مثل en (انگلیسی) یا fr (فرانسوی) را به سیستم میدهید، الگوریتمهای داخلی جاوااسکریپت بقیه اطلاعات را حدس میزنند (برای درک این موضوع متد Intl.Locale.prototype.maximize() را ببینید).
منطقه یا کشور (Region): در بیشتر مواقع ترجیح میدهید کشور را هم مشخص کنید؛ چرا که قراردادها بین کشورهایی که به یک زبان واحد صحبت میکنند، میتواند زمین تا آسمان متفاوت باشد! به عنوان مثال، فرمت تاریخ در آمریکا MM/DD/YYYY است، در حالی که در انگلیس به صورت DD/MM/YYYY نوشته میشود؛ بنابراین مشخص کردن دقیق en-US یا en-GB بسیار حیاتی است.
خط نگارشی (Script): سیستم نوشتاری یا کاراکترهایی است که برای نوشتن آن زبان استفاده میشود. در عمل، مشخص کردن خط نگارشی معمولاً نیازی نیست، چون زبانِ یک منطقه خاص اغلب فقط با یک خط نوشته میشود. اما استثناهایی هم وجود دارد؛ مثلاً زبان صربی را میتوان هم با خط لاتین و هم سیریلیک نوشت (sr-Latn و sr-Cyrl)، یا زبان چینی که با دو خطِ سادهشده و سنتی نوشته میشود (zh-Hans و zh-Hant).
گویشها یا گونهها (Variants): به ندرت استفاده میشوند و معمولاً نشاندهنده شیوههای نگارشیِ متفاوت در دورههای زمانی مختلف هستند؛ مثلاً زبان آلمانی دارای دو گونه نگارشیِ سالهای ۱۹۰۱ و ۱۹۹۶ است که به صورت de-1901 و de-1996 نوشته میشوند.
بیا یک نمونه کد ساده از نحوه تفسیر این ساختار را ببینیم:
// این دو مورد زمان پاس داده شدن به دیگر APIهای Intl کاملاً با هم برابر هستند
const locale1 = new Intl.Locale("en-US");
const locale2 = new Intl.Locale("en-Latn-US");
console.log(locale1.language, locale1.script, locale1.region); // "en", undefined, "US"
console.log(locale2.language, locale2.script, locale2.region); // "en", "Latn", "US"
یک لوکال همچنین شامل مجموعهای از قراردادها و ترجیحاتِ مورد استفاده در آن فرهنگِ خاص است که در جدول زیر به طور کامل دستهبندی شدهاند:
| کاربرد | نام ویژگی (Property) | توضیحات | پسوند تگ زبان (Subtag) |
| فرمت تاریخ و زمان | calendar | برای گروهبندی روزها در قالب سال، ماه و هفته و نامگذاری آنها استفاده میشود. برای مثال، تاریخ میلادی "2022-01-01" در تقویم عبری به "28 Tevet 5782" تبدیل میشود. | ca |
hourCycle | مشخص میکند که زمان به صورت ۱۲ ساعته نمایش داده شود یا ۲۴ ساعته، و اینکه کوچکترین عدد ساعت ۰ باشد یا ۱. | hc | |
| فرمت اعداد (شامل تاریخ، زمان، مدتزمان و...) | numberingSystem | اعداد را به سیستم نگارشیِ مخصوص آن زبان تبدیل میکند. سیستم معمولی 0123456789 را latn (لاتین) مینامند. اغلب هر خطِ نگارشی یک سیستم عددی دارد که صرفاً ترجمه کاراکتر به کاراکتر است، اما برخی خطوط بیش از یک سیستم عددی دارند، برخی به طور سنتی اعداد را با آن خط نمینویسند (مثلاً چینی سیستم عددی hanidec خود را دارد اما اکثر متون از سیستم استاندارد latn استفاده میکنند)، و برخی دیگر به الگوریتمهای تبدیل خاصی نیاز دارند (مثل اعداد رومی یا همان roman). | nu |
| تطبیق و مرتبسازی (Collation) | collation | الگوریتم کلی مرتبسازی متون را تعریف میکند. به عنوان مثال، اگر از سیستم مرتبسازی دفترچه تلفن آلمانی (phonebk) استفاده کنید، حرف "ä" مانند "ae" در نظر گرفته میشود و در مرتبسازی بین "ad" و "af" قرار میگیرد. | co |
caseFirst | مشخص میکند که آیا حروف بزرگ باید زودتر از حروف کوچک مرتب شوند، یا حروف کوچک اولویت دارند، یا اینکه کلاً بزرگ و کوچکی حروف نادیده گرفته شود. | kf | |
numeric | تعیین میکند که آیا اعداد داخل متن باید به عنوان عدد مرتب شوند یا به عنوان رشته متنی. برای مثال، اگر مقدار آن true باشد، رشته "10" بعد از "2" قرار میگیرد (چون عدد ۱۰ بزرگتر از ۲ است). | kn |
شما میتوانید این ویژگیها را در زمان ساخت شیء Intl.Locale یا هنگام پاس دادن تگهای زبان به سایر سازندههای Intl به صورت صریح مشخص کنید. برای این کار دو روش وجود دارد: چسباندن آنها به تگ زبان یا مشخص کردن آنها در قالب گزینهها (Options).
روش اول (افزودن به تگ زبان): ابتدا رشته -u (به معنی پسوند یونیکد) را به انتهای تگ زبان اضافه میکنید، سپس پسوند ویژگی (Subtag) که در جدول بالا گفته شد را مینویسید و بعد مقدار آن را وارد میکنید.
روش دوم (تعریف در شیء گزینهها): خیلی راحت نام دقیق ویژگی (Property) و مقدار آن را به شیء گزینهها (options) اضافه میکنید.
اگر برای نمونه از Intl.DateTimeFormat استفاده کنیم، هر دو خط کد زیر کاملاً مشابه هم عمل کرده و یک فرمتکننده بر اساس تقویم عبری میسازند:
// روش اول: اضافه کردن مستقیم به انتهای تگ زبان
const df1 = new Intl.DateTimeFormat("en-US-u-ca-hebrew");
// روش دوم: تعریف به صورت یک گزینه در شیء Options
const df2 = new Intl.DateTimeFormat("en-US", { calendar: "hebrew" });
📌 نکته: ویژگیهای ناشناخته و نامربوط توسط سیستم نادیده گرفته میشوند. مثلاً اگر ساختار بالا را در
Intl.NumberFormatبنویسید، هیچ تغییری در خروجی ایجاد نمیکند و تفاوتی با پاس دادنِ سادهیen-USندارد؛ چون فرمت کردن اعداد اصلاً از ویژگی تقویم (calendar) استفاده نمیکند.
به دست آوردن مقادیر پیشفرض این قراردادها کمی ظریف است. اگر بنویسید new Intl.Locale("en-US").calendar، مقدار undefined را دریافت میکنید؛ زیرا شیء Locale فقط و فقط حاوی اطلاعاتی است که شما به صورت صریح به آن پاس دادهاید.
تقویم پیشفرض تئوریک، کاملاً به این بستگی دارد که از آن لوکال در چه APIای استفاده میکنید! بنابراین برای به دست آوردن تقویم پیشفرض لوکالِ en-US زمانی که در Intl.DateTimeFormat استفاده میشود، باید از متد resolvedOptions() استفاده کنید. این قاعده برای سایر ویژگیها هم برقرار است:
const locale = new Intl.Locale("en-US");
console.log(locale.calendar); // خروجی: undefined (چون دستی واردش نکردیم)
// دریافت تقویم واقعی پیشفرض از طریق متد resolvedOptions
console.log(new Intl.DateTimeFormat(locale).resolvedOptions().calendar); // خروجی: "gregory"
اشیای Intl.Locale دو کار را به طور همزمان انجام میدهند: اول اینکه نماینده یک تگ زبانِ تجزیهشده (Parsed BCP 47) هستند، و دوم اینکه اطلاعاتی درباره آن لوکال ارائه میدهند. تمام ویژگیهای مستقیم آن (مثل calendar) فقط از روی ورودیِ شما استخراج میشوند، بدون اینکه هیچ منبع دادهای را برای پیدا کردن مقادیر پیشفرض جستجو کنند.
اما در طرف مقابل، این شیء مجموعهای از متدها دارد که کارشان پرسوجو و استخراج اطلاعات واقعی و دنیای حقیقی درباره آن لوکال است! برای مثال، متدهای getCalendars()، getHourCycles()، getNumberingSystems() و getCollations() مکمل همان ویژگیهای جدول بالا هستند و هر کدام یک آرایه از تمام مقادیر محبوب و ترجیح داده شده در آن فرهنگ را برمیگردانند:
const locale = new Intl.Locale("ar-EG"); // لوکال عربی مصر
// دریافت تمام تقویمهای رایج و مورد استفاده در مصر به ترتیب اولویت:
console.log(locale.getCalendars());
// خروجی: ['gregory', 'coptic', 'islamic', 'islamic-civil', 'islamic-tbla']
علاوه بر این موارد، نمونههای Intl.Locale شامل متدهای کاربردی دیگری هم هستند که اطلاعات بسیار مفیدی را به بیرون عرضه میکنند؛ از جمله:
getTextInfo(): دریافت اطلاعات درباره جهت متن (مثلاً راستچین یا چپچین بودن خط).
getTimeZones(): دریافت لیست مناطق زمانی رسمی آن لوکال.
getWeekInfo(): دریافت اطلاعات مربوط به روزهای هفته (مثل اینکه روز شروع هفته در آن فرهنگ چه روزی است).
این محتوا کاملا رایگان توسط تیم کدلپر ترجمه شده و در اختیار شما کاربران عزیز قرار گرفته است، هر گونه کپی برداری برای مقاصد غیر رایگان و بدون ذکر منبع، مورد پیگیری قانونی قرار میگیرد.
ترجمه شده از منبع: https://developer.mozilla.org/en-US/docs/Web/JavaScript