Mundarija (42)
- Bu darsda
- 1. Nega bu kerak?
- 2. Oddiy son
- 2.1 Uch til, uch qoida
- 2.2 toLocaleString — qisqa yo'l
- 3. Valyuta: so'm
- 3.1 style: "currency"
- 3.2 Uch tilda va valyuta ko'rinishi
- 3.3 Buxgalteriya uslubi
- 4. Foiz va ishora
- 4.1 style: "percent"
- 4.2 signDisplay — ishorani ko'rsatish
- 5. Kasr xonalari va yaxlitlash
- 5.1 Nechta kasr xona
- 5.2 Yaxlitlash rejimi
- 5.3 500 so'mga yaxlitlash
- 6. Qisqa sonlar va birliklar
- 6.1 notation: "compact" — "1,5 mln"
- 6.2 style: "unit" — kg, km, daqiqa
- 7. Bo'laklar va oraliqlar
- 7.1 formatToParts
- 7.2 formatRange — "dan … gacha"
- 7.3 Juda katta va aniq sonlar
- 8. Formatlovchini bir marta yarating
- 9. Node va Chrome: 75 000 yoki 75,000
- 9.1 Farq
- 9.2 Nega?
- 9.3 Har ikki muhitda bir xil natija
- 10. Ko'p uchraydigan xatolar
- 10.1 Foizni 100 ga ko'paytirib berish
- 10.2 Valyuta kodi o'rniga so'z
- 10.3 Formatlangan matnni songa qaytarish
- 10.4 Formatlovchini sikl ichida yaratish
- 10.5 Formatlangan matnni testda solishtirish
- 11. Mashqlar
- 1-mashq (oson): Menyu narxlari
- 2-mashq (o'rta): Narx o'zgarishi
- 3-mashq (qiyin): Og'irlik — har ikki muhitda bir xil
- 4-mashq: Vazifalar qadami — narx formati yordamchisi
- 12. Real ishda
- Xulosa
- Manbalar
JavaScript Intl.NumberFormat: so'm, foiz, kg va katta sonlarni to'g'ri formatlash
Qisqacha:
Intl.NumberFormatsonni til qoidalari bo'yicha matnga aylantiradi:new Intl.NumberFormat("uz", { style: "currency", currency: "UZS", maximumFractionDigits: 0 }).format(35000)→"35 000 soʻm".stylebilan valyuta, foiz yoki birlik (kg, km) tanlanadi,notation: "compact"—"1,5 mln",formatToParts— natijani bo'laklarga bo'ladi. Formatlovchini bir marta yaratib, ko'p marta ishlating. Chrome 154 da o'zbekcha son qoidalari yo'q —"UZS 35,000"chiqadi.
Bu darsda
- Narxni so'mda, foizni, og'irlik va masofani uch tilda formatlaysiz.
- Kasr xonalari, yaxlitlash rejimi va
roundingIncrementbilan narxni 500 so'mga yaxlitlaysiz. notation: "compact",signDisplay,formatToPartsvaformatRangeni ishlatasiz.- Formatlovchini bir marta yaratish nega o'nlab marta tezroq ekanini o'lchov bilan ko'rasiz.
- Chrome'dagi
75,000muammosining sababini bilasiz va har ikki muhitda bir xil ishlaydigansomYozfunksiyasini yozasiz.
Oldin bilishingiz kerak: Intl.RelativeTimeFormat, Intl.DateTimeFormat, Math obyekti, Pul va aniq hisob-kitob.
1. Nega bu kerak?
08-qismda bu asbobni ikki marta ko'rgan edik. Math obyekti darsida 1234567 ni 1 234 567 qildik. Pul va aniq hisob-kitob darsida esa narxga soʻm qo'shdik. Ikkalasida ham "to'liq imkoniyatlari keyin" degan edik. Bugun o'sha kun.
«Bahor» menyusida narxlar hozir shunday: Osh — 35000. O'qish qiyin. Sardor buni regex bilan tuzatdi — Lookahead darsidagi mashhur naqsh:
const narx = 35000;
const chiroyli = String(narx).replace(/\B(?=(\d{3})+(?!\d))/g, " ");
console.log(`${chiroyli} so'm`); // 35 000 so'mIshlaydi. Lekin keyin uch muammo chiqdi:
- Ruscha saytda ham bo'sh joy kerak, inglizchada esa vergul:
35,000. Nemischada — nuqta:35.000. - Kasr qism: o'zbek va rus tilida vergul (
2,5 kg), ingliz tilida nuqta (2.5 kg). - Jasur aka "1 500 000 ni
1,5 mlnqilib ko'rsat" dedi.
Har til uchun alohida regex va if — bu yana o'sha "qo'lda qoidalar" yo'li. O'tgan darsda ko'rdik: bu qoidalar ICU ichida tayyor turibdi. Sonlar uchun eshik — Intl.NumberFormat.
2. Oddiy son
2.1 Uch til, uch qoida
const son = 1234567.891;
console.log(new Intl.NumberFormat("uz").format(son)); // 1 234 567,891
console.log(new Intl.NumberFormat("ru").format(son)); // 1 234 567,891
console.log(new Intl.NumberFormat("en").format(son)); // 1,234,567.891
console.log(new Intl.NumberFormat("de").format(son)); // 1.234.567,891Bir son — to'rt xil yozuv. Minglarni ajratuvchi belgi (bo'sh joy, vergul, nuqta) va kasr belgisi (vergul yoki nuqta) tilga qarab tanlanadi. Hindistonda esa minglar umuman boshqacha guruhlanadi: en-IN da 12345678 → 1,23,45,678.
O'zbek tilidagi bo'sh joy — oddiy bo'sh joy emas, uzilmas bo'sh joy (U+00A0). Uni Matn ↔ son va sonni tekshirish darsida ko'rgansiz: qator oxirida son ikkiga bo'linib ketmasligi uchun.
2.2 toLocaleString — qisqa yo'l
Sonning o'zida ham shunday metod bor:
const narx = 35000;
console.log(narx.toLocaleString("uz")); // 35 000
console.log(narx.toLocaleString("en-US")); // 35,000toLocaleString(til, sozlamalar) ichida aynan Intl.NumberFormat ishlaydi va sozlamalari ham bir xil. Bitta sonni bir marta formatlash uchun qulay. Ko'p son uchun esa sekin — buni «Formatlovchini bir marta yarating» bo'limida o'lchaymiz.
Diqqat: Bu darsdagi "Konsolda" natijalari Node 24 da olingan. «Ishga tushir» tugmasi kodni brauzeringizda bajaradi, Chrome'da esa
uznatijalari boshqacha chiqadi (35,000). Sababini «Node va Chrome: 75 000 yoki 75,000» bo'limida ochamiz.
3. Valyuta: so'm
3.1 style: "currency"
const som = new Intl.NumberFormat("uz", {
style: "currency",
currency: "UZS",
});
console.log(som.format(35000)); // 35 000,00 soʻmIkki sozlama birga keladi:
style: "currency"— "bu pul";currency: "UZS"— qaysi valyuta. Kod — xalqaro ISO 4217 standartidagi uch harf:UZS— so'm,USD— dollar,RUB— rubl,EUR— yevro.
,00 nimadan? Standart bo'yicha so'm ikki kasr xonali — tiyin bilan. Kundalik narxlarda tiyin ishlatilmaydi, shuning uchun uni o'chiramiz:
const som = new Intl.NumberFormat("uz", {
style: "currency",
currency: "UZS",
maximumFractionDigits: 0,
});
console.log(som.format(35000)); // 35 000 soʻm
console.log(som.format(5000)); // 5 000 soʻm
console.log(som.format(-35000)); // -35 000 soʻmmaximumFractionDigits: 0 — "kasr qism ko'pi bilan 0 xona". Endi narx «Bahor» menyusidagidek.
soʻm dagi belgiga e'tibor bering: bu oddiy ' emas, ʻ (U+02BB). Til bazasi o'zbek lotin yozuvidagi rasmiy belgini ishlatadi. O'tgan darsda o‘tgan hafta da esa boshqa belgi edi — ‘ (U+2018). Bitta bazada ikki xil yozuv — formatlangan matnni solishtirmaslik uchun yana bir sabab.
3.2 Uch tilda va valyuta ko'rinishi
So'mni uch tilda formatlasak:
| Til | format(35000) |
currencyDisplay: "name" |
|---|---|---|
uz |
35 000 soʻm |
35 000 O‘zbekiston so‘mi |
ru |
35 000 UZS |
35 000 узбекских сумов |
en |
UZS 35,000 |
35,000 Uzbekistani som |
Jadvalda maximumFractionDigits: 0 ishlatilgan. Rus va ingliz tillarida so'mning qisqa belgisi yo'q, shuning uchun kod — UZS — chiqadi. Valyuta qanday ko'rinishini currencyDisplay boshqaradi:
"symbol"(standart) — belgi:soʻm,$,€;"code"— kod:UZS;"name"— to'liq nom, ruschada son bilan moslashadi:1 узбекский сум,2 узбекских сума;"narrowSymbol"— eng qisqa belgi.
Boshqa valyutalar o'zbekcha formatda: 12,50 US$, 1 500,00 €. Ingliz tilida esa belgi sondan oldin: $12.50.
3.3 Buxgalteriya uslubi
Hisobotlarda manfiy summa ko'pincha qavsda yoziladi. Buning uchun currencySign: "accounting":
const hisob = new Intl.NumberFormat("en", {
style: "currency",
currency: "USD",
currencySign: "accounting",
});
console.log(hisob.format(-35)); // ($35.00)Tekshirib ko'ring:
new Intl.NumberFormat("uz", { style: "currency" }).format(5)nima beradi?
Javob
Xato: TypeError: Currency code is required with currency style. — "Valyuta uslubida valyuta kodi majburiy". Formatlovchi qaysi pul ekanini bilmasa, belgini ham, kasr xonalari sonini ham tanlay olmaydi.
4. Foiz va ishora
4.1 style: "percent"
«Bahor»da tushlik vaqtida 15% chegirma bor:
const foiz = new Intl.NumberFormat("uz", { style: "percent" });
console.log(foiz.format(0.15)); // 15%
console.log(foiz.format(15)); // 1 500%Ikkinchi qator — tuzoq. percent sonni 100 ga ko'paytiradi: u 0.15 ni "ulush" deb tushunadi. Ma'lumotda 15 saqlangan bo'lsa, avval 100 ga bo'ling. Rus tilida foiz belgisi sondan bo'sh joy bilan ajraladi: 15 %.
4.2 signDisplay — ishorani ko'rsatish
Narx o'zgarishini ko'rsatganda + belgisi ham kerak: "+12%", "-5%". Standart holatda faqat minus chiqadi. signDisplay buni boshqaradi:
const ozgarish = new Intl.NumberFormat("uz", {
style: "percent",
signDisplay: "exceptZero",
});
console.log(ozgarish.format(0.12)); // +12%
console.log(ozgarish.format(-0.05)); // -5%
console.log(ozgarish.format(0)); // 0%| Qiymat | 5 |
-5 |
0 |
|---|---|---|---|
"auto" (standart) |
5 |
-5 |
0 |
"always" |
+5 |
-5 |
+0 |
"exceptZero" |
+5 |
-5 |
0 |
"never" |
5 |
5 |
0 |
Yana bir qiymat — "negative": faqat haqiqiy manfiylarga minus qo'yadi va -0 ni 0 qiladi. Standart holatda esa format(-0) — -0. -0 ni Number turi ichidan darsida ko'rgansiz.
Tekshirib ko'ring: Ma'lumotlar bazasida chegirma
20deb saqlangan. Uni"20%"qilib chiqarish uchunformatga nima berasiz?
Javob
format(20 / 100), ya'ni 0.2. percent uslubi sonni 100 ga ko'paytiradi. Boshqa yo'li — style: "unit", unit: "percent": u ko'paytirmaydi va format(20) → 20%.
5. Kasr xonalari va yaxlitlash
5.1 Nechta kasr xona
Uch sozlama bor:
minimumFractionDigits— kamida nechta (yetmasa, nol qo'shiladi);maximumFractionDigits— ko'pi bilan nechta (ortig'i yaxlitlanadi);maximumSignificantDigits— jami nechta muhim raqam. Muhim raqamlar — sonning boshidagi noldan farqli raqamdan boshlab sanaladi:35780ni 2 ta muhim raqamga qisqartirsak,36 000(3 va 6 qoladi, qolgani nol).
const nf = (sozlama) => new Intl.NumberFormat("uz", sozlama);
console.log(nf({ minimumFractionDigits: 2 }).format(5)); // 5,00
console.log(nf({ maximumFractionDigits: 2 }).format(3.14159)); // 3,14
const ikkiRaqam = nf({ maximumSignificantDigits: 2 });
console.log(ikkiRaqam.format(35780)); // 36 000
console.log(nf({ minimumIntegerDigits: 2 }).format(7)); // 07Oxirgisi — minimumIntegerDigits — butun qismni nol bilan to'ldiradi: soat va daqiqa uchun qulay (07:05).
Yana bir foydali farq. Pul va aniq hisob-kitob darsida toFixed ning yaxlitlash tuzog'ini ko'rgan edik:
const nf = new Intl.NumberFormat("uz", { maximumFractionDigits: 2 });
console.log((1.005).toFixed(2)); // 1.00
console.log(nf.format(1.005)); // 1,01toFixed sonning ikkilik tizimdagi aniq qiymatidan (1.00499…) yaxlitlaydi. Intl.NumberFormat esa sonning o'nlik yozuvidan (1.005) — odam kutgan natija chiqadi. Baribir, pulni hisoblash — butun tiyinda; formatlash faqat ko'rsatish uchun.
5.2 Yaxlitlash rejimi
Standart yaxlitlash — maktabdagidek: .5 va undan katta — yuqoriga (2.5 → 3). Buni roundingMode o'zgartiradi:
roundingMode |
2.5 |
2.9 |
-2.5 |
|---|---|---|---|
"halfExpand" (standart) |
3 |
3 |
-3 |
"halfEven" |
2 |
3 |
-2 |
"ceil" |
3 |
3 |
-2 |
"floor" |
2 |
2 |
-3 |
"trunc" |
2 |
2 |
-2 |
halfEven — "bank yaxlitlashi": .5 eng yaqin juft songa boradi. Ko'p sonni yaxlitlaganda xatolar bir tomonga to'planib qolmaydi.
5.3 500 so'mga yaxlitlash
Do'konlarda narx ko'pincha 500 yoki 1 000 so'mga yaxlitlanadi: maydalari yo'q. roundingIncrement aynan shu:
const yaxlit = new Intl.NumberFormat("uz", {
maximumFractionDigits: 0,
roundingIncrement: 500,
});
const yuqoriga = new Intl.NumberFormat("uz", {
maximumFractionDigits: 0,
roundingIncrement: 500,
roundingMode: "ceil",
});
console.log(yaxlit.format(35200)); // 35 000
console.log(yuqoriga.format(35200)); // 35 500roundingIncrement faqat ma'lum qiymatlarni qabul qiladi: 1, 2, 5, 10, 20, 25, 50, 100, 200, 250, 500, 1000, 2000, 2500, 5000. 3 bersangiz — RangeError. Va u maximumFractionDigits bilan birga ishlaydi.
Diqqat: Bu yaxlitlash faqat ekrandagi matnni o'zgartiradi. Hisobdagi son o'sha-o'sha
35200bo'lib qoladi. Mijozdan haqiqatan 35 500 so'm olinadigan bo'lsa, summani hisob paytida yaxlitlang, formatlashda emas.
O'zingiz to'ldiring: 0.07 ni "7%" qilib chiqarish uchun style sozlamasiga qiymatini berasiz.
6. Qisqa sonlar va birliklar
6.1 notation: "compact" — "1,5 mln"
Statistika sahifasida katta sonlar joy egallaydi. notation: "compact" ularni qisqartiradi:
const qisqa = new Intl.NumberFormat("uz", { notation: "compact" });
console.log(qisqa.format(1500)); // 1,5 ming
console.log(qisqa.format(35000)); // 35 ming
console.log(qisqa.format(1500000)); // 1,5 mln
console.log(qisqa.format(2500000000)); // 2,5 mlrdcompactDisplay: "long" bilan so'z to'liq yoziladi: 1,5 million. Rus tilida — 1,5 млн va 1,5 миллиона, ingliz tilida — 1.5M va 1.5 million.
Valyuta bilan ham birga ishlaydi — «Bahor»ning oylik tushumi uchun:
const tushum = new Intl.NumberFormat("uz", {
notation: "compact",
style: "currency",
currency: "UZS",
});
console.log(tushum.format(1500000)); // 1,5 mln soʻmQisqa yozuv aniqlikni yo'qotadi: 1 234 567 ham 1,2 mln bo'ladi. Aniqroq kerak bo'lsa, maximumFractionDigits: 2 qo'shing — 1,23 mln.
6.2 style: "unit" — kg, km, daqiqa
Yetkazib berish sahifasida: "2,5 kg", "3,2 km", "25 daqiqa". Buning uchun style: "unit":
const birlik = (unit, unitDisplay = "short") =>
new Intl.NumberFormat("uz", { style: "unit", unit, unitDisplay });
console.log(birlik("kilogram").format(2.5)); // 2,5 kg
console.log(birlik("kilometer").format(3.2)); // 3,2 km
console.log(birlik("minute", "long").format(25)); // 25 daqiqa
console.log(birlik("liter", "long").format(1.5)); // 1,5 litr
console.log(birlik("kilometer-per-hour").format(60)); // 60 km/soatBirlik nomlari — standart ro'yxatdan, inglizcha: kilogram, gram, liter, meter, kilometer, minute, hour, celsius, percent, megabyte va boshqalar (Node 24 da jami 45 ta). Ikkitasini -per- bilan bog'lash mumkin: kilometer-per-hour. unitDisplay — "short" (standart), "long" yoki "narrow".
Ro'yxatda "dona" yo'q: unit: "dona" → RangeError: Invalid unit argument for Intl.NumberFormat() 'dona'. "3 dona" kabi matnni o'zingiz yasaysiz.
Tekshirib ko'ring:
notation: "compact"bilan999nima bo'ladi?
Javob
"999". Qisqartirish mingdan boshlanadi. Mingdan kichik sonni qisqartiradigan so'z yo'q.
7. Bo'laklar va oraliqlar
7.1 formatToParts
O'tgan darsdagidek, NumberFormat ham natijani bo'laklarga bo'ladi:
const som = new Intl.NumberFormat("uz", {
style: "currency",
currency: "UZS",
maximumFractionDigits: 0,
});
console.log(som.formatToParts(35000));Konsolda:
[
{ type: 'integer', value: '35' },
{ type: 'group', value: ' ' },
{ type: 'integer', value: '000' },
{ type: 'literal', value: ' ' },
{ type: 'currency', value: 'soʻm' }
]type lari: integer — butun qism, group — minglar ajratuvchisi, decimal — kasr belgisi, fraction — kasr qism, currency — valyuta, percentSign, unit, minusSign, literal. Dizayner "so'm kichikroq va kulrang bo'lsin" desa — currency bo'lagini alohida <span> ga o'raysiz. Bo'laklar tartibi tilga bog'liq: ingliz tilida currency birinchi keladi.
7.2 formatRange — "dan … gacha"
Menyu sarlavhasida narxlar oraliq bilan yozilishi kerak: 5 000–35 000 soʻm (ko'k choydan oshgacha). Ikki sonni alohida formatlab, chiziqcha qo'yish mumkin. Lekin formatRange valyutani bir marta yozadi:
const som = new Intl.NumberFormat("uz", {
style: "currency",
currency: "UZS",
maximumFractionDigits: 0,
});
console.log(som.formatRange(5000, 35000)); // 5 000–35 000 soʻm
console.log(som.formatRange(35000, 35000)); // ~35 000 soʻmIkki son teng bo'lsa — ~ (taxminan) belgisi bilan bitta son. Ingliz tilida dollar har ikki songa qo'yiladi: $3.00 – $5.00.
7.3 Juda katta va aniq sonlar
Metod oddiy sondan tashqari BigInt ni va satr ko'rinishidagi sonni ham qabul qiladi:
const nf = new Intl.NumberFormat("uz");
const katta = "12345678901234567890";
console.log(nf.format(Number(katta)));
console.log(nf.format(BigInt(katta)));
console.log(nf.format(`${katta}.55`));Konsolda:
12 345 678 901 234 567 000
12 345 678 901 234 567 890
12 345 678 901 234 567 890,55Birinchi qatorda oxirgi raqamlar yo'qoldi — oddiy son buncha aniqlikni sig'dirmaydi (BigInt darsidagi sabab). BigInt va satr esa raqamlarni aynan saqlaydi. Bank yoki birja ma'lumotlarida summa ko'pincha satr bo'lib keladi — uni songa aylantirmasdan formatlash mumkin.
8. Formatlovchini bir marta yarating
new Intl.NumberFormat(...) — og'ir ish: til ma'lumotlari qidiriladi, qoidalar tayyorlanadi. toLocaleString ham har chaqiruvda xuddi shu ishni qiladi. Formatlovchi bir marta yaratilsa, keyingi format lar faqat tayyor qoidani qo'llaydi.
Biz 10 000 ta narxni uch usulda formatlab, vaqtni o'lchadik:
// 1) har narxda toLocaleString
narxlar.map((n) => n.toLocaleString("uz-UZ", sozlama));
// 2) har narxda yangi formatlovchi
narxlar.map((n) =>
new Intl.NumberFormat("uz-UZ", sozlama).format(n),
);
// 3) bitta tayyor formatlovchi
const som = new Intl.NumberFormat("uz-UZ", sozlama);
narxlar.map((n) => som.format(n));- toLocaleStringhar chaqiruvda qoidalar qaytadan430 ms
- har safar newhar narxga yangi formatlovchi470 ms
- tayyor formatlovchibir marta yaratilgan6 ms
Manba: O'lchov: Node 24.21.0, Intel Core i5-12500H, Windows 11; har usul 7 marta, mediana; 3 ta ishga tushirish medianalarining medianasi, yaxlitlangan (2026-10-05)
Nimaga qarang: tayyor formatlovchi taxminan 70 marta tez. Sizning kompyuteringizda raqamlar boshqacha chiqadi, lekin farqning kattaligi o'xshash bo'ladi. Qoida: formatlovchini modul darajasida bir marta yarating va hamma joyda ishlating. Tezlikni qanday o'lchashni Performansni o'lchash va benchmarking darsida o'rganamiz.
9. Node va Chrome: 75 000 yoki 75,000
9.1 Farq
Pul va aniq hisob-kitob darsida "Chrome'da uz-UZ minglarni vergul bilan ajratadi" degan edik. Biz buni Node 24.21 (ICU 78.3) va Chrome 154.0.8037.95 da qayta sinadik:
Kod (uz) |
Node 24 | Chrome 154 |
|---|---|---|
format(75000) |
75 000 |
75,000 |
format(2.5) |
2,5 |
2.5 |
| so'm, 0 xona | 35 000 soʻm |
UZS 35,000 |
compact: 1500000 |
1,5 mln |
1.5M |
unit, liter, long |
1,5 litr |
1.5 liters |
format(NaN) |
son emas |
NaN |
Rus va ingliz tillari uchun esa natijalar aynan bir xil — biz bu darsdagi barcha ru va en misollarini Chrome'da ham sinadik. Chrome ustuni — brauzer tili en-US bo'lganda. Zaxira ba'zi joylarda brauzer tiliga qaraydi: ruscha Chrome'da oxirgidan oldingi qator 1.5 литра bo'ladi.
9.2 Nega?
O'tgan darsdagi sabab: Chrome ICU ma'lumotlarini qisqartirib olib yuradi. Biz sinagan 154-versiyada (kompyuter) o'zbek lotin (uz) tilining son qoidalari (ajratuvchilar, soʻm, mln) yo'q. Chrome umumiy zaxira shablonga qaytadi — u inglizchaga o'xshaydi: vergul, nuqta, valyuta kodi oldinda. Bu faqat o'zbekchaga xos emas: qozoq (kk), qirg'iz (ky), tojik (tg) va ozarbayjon (az) tillari ham Chrome'da 35,000 beradi.
Va yana o'sha xavf — Chrome buni tan olmaydi:
const nf = new Intl.NumberFormat("uz-UZ");
console.log(nf.resolvedOptions().locale);
console.log(Intl.NumberFormat.supportedLocalesOf(["uz"]));
// Chrome 154: "uz-UZ" va [ 'uz' ] — Node 24 bilan bir xilIkkalasi ham "o'zbek tili bor" deydi. Faqat natijaning o'zi haqiqatni ko'rsatadi.
9.3 Har ikki muhitda bir xil natija
«Bahor» saytida narx mehmon telefonidagi brauzerda ko'rinadi. Qaysi brauzer bo'lishini bilmaymiz. Bizga esa har joyda 35 000 so'm kerak. formatToParts bu yerda qutqaradi: raqamlar va guruhlash formatlovchidan, ajratuvchi va so'z — bizdan.
const raqam = new Intl.NumberFormat("uz-UZ", {
maximumFractionDigits: 0,
});
function somYoz(narx) {
const matn = raqam
.formatToParts(narx)
.map((b) => (b.type === "group" ? "\u00a0" : b.value))
.join("");
return `${matn} so'm`;
}
console.log(somYoz(35000)); // 35 000 so'm
console.log(somYoz(1250000)); // 1 250 000 so'mChrome'da group bo'lagi , bo'lib keladi, Node'da — uzilmas bo'sh joy. Biz ikkalasini ham "\u00a0" — uzilmas bo'sh joy bilan almashtiramiz. so'm ni o'zimiz yozdik — saytdagi boshqa matnlar bilan bir xil oddiy apostrof bilan. Natija ikkala muhitda bir xil — buni Chrome 154 da tekshirdik.
Bu yechim butun sonlar uchun. Kasrli son kerak bo'lsa, decimal bo'lagini ham "," ga almashtirish kerak bo'ladi — 3-mashqda shuni qilasiz.
Tekshirib ko'ring: Nega
somYozda"uz-UZ"o'rniga"ru-RU"yozib qo'yish ham ishlaydi, lekin yaxshi yechim emas?
Javob
ru qoidalari Chrome'da bor va minglarni ham uzilmas bo'sh joy bilan ajratadi — natija bir xil chiqadi. Lekin kodni o'qigan odam "nega o'zbek saytida rus tili?" deb chalg'iydi. Ertaga rus qoidalari o'zgarsa, o'zbekcha narx ham kutilmaganda o'zgaradi. formatToParts bilan esa niyat aniq: "raqamni formatla, ajratuvchini o'zim qo'yaman".
10. Ko'p uchraydigan xatolar
10.1 Foizni 100 ga ko'paytirib berish
format(15) → 1 500%. percent o'zi ko'paytiradi. Ulush bering (0.15) yoki unit: "percent" ishlating.
10.2 Valyuta kodi o'rniga so'z
const som = new Intl.NumberFormat("uz", {
style: "currency",
currency: "so'm",
});RangeError: Invalid currency code : so'mTarjimasi: "Valyuta kodi noto'g'ri: so'm". Kod — faqat uch lotin harfi, ISO 4217 bo'yicha: UZS. Ehtiyot bo'ling: "SOM" xato bermaydi (uch harf — shakli to'g'ri), lekin bunday valyuta yo'q va natijada 5,00 SOM chiqadi.
10.3 Formatlangan matnni songa qaytarish
console.log(Number("35 000")); // NaN
console.log(Number.parseInt("35 000")); // 35parseInt birinchi bo'sh joyda to'xtadi va 35 qaytardi — xato bermasdan. Formatlangan matn — faqat ekran uchun. Sonni doim alohida, formatlanmagan holda saqlang.
10.4 Formatlovchini sikl ichida yaratish
map ichida new Intl.NumberFormat yoki toLocaleString — 10 000 narxda yarim soniya. Formatlovchini sikldan tashqarida, bir marta yarating.
10.5 Formatlangan matnni testda solishtirish
expect(som.format(35000)).toBe("35 000 so'm") — test kutubxonalarida "natija shunga teng bo'lsin" degan yozuv. Bunday test ikki joyda yiqiladi: bo'sh joy uzilmas (U+00A0), apostrof esa ʻ (U+02BB). Ustiga-ustak, Chrome'da natija butunlay boshqa. Testda formatlovchining o'zini emas, o'zingizning somYoz kabi funksiyangizni tekshiring. Testlarni node:test darsida yozamiz.
11. Mashqlar
1-mashq (oson): Menyu narxlari
«Bahor» menyusi: osh 35 000, lag'mon 28 000, manti 30 000, ko'k choy 5 000. Har taomni Osh — 35 000 soʻm ko'rinishida chiqaring. Formatlovchini bir marta yarating. Ishora: style: "currency", currency: "UZS", maximumFractionDigits: 0.
Yechim
const som = new Intl.NumberFormat("uz", {
style: "currency",
currency: "UZS",
maximumFractionDigits: 0,
});
const menyu = [
{ nom: "Osh", narx: 35000 },
{ nom: "Lag'mon", narx: 28000 },
{ nom: "Manti", narx: 30000 },
{ nom: "Ko'k choy", narx: 5000 },
];
for (const { nom, narx } of menyu) {
console.log(`${nom} — ${som.format(narx)}`);
}Konsolda:
Osh — 35 000 soʻm
Lag'mon — 28 000 soʻm
Manti — 30 000 soʻm
Ko'k choy — 5 000 soʻmFormatlovchi sikldan oldin bir marta yaratildi. Taom nomlarida — oddiy apostrof (biz yozdik), soʻm da — ʻ (formatlovchi yozdi).
2-mashq (o'rta): Narx o'zgarishi
ozgarishniYoz(eski, yangi) funksiyasi narx necha foiz o'zgarganini +14,3% yoki -10% ko'rinishida qaytarsin: ko'pi bilan bitta kasr xona, nol bo'lsa ishorasiz. Uni uch juftlikda sinang: 35 000 → 40 000, 30 000 → 27 000, 5 000 → 5 000. Ishora: o'zgarish ulushi — (yangi - eski) / eski; signDisplay: "exceptZero".
Yechim
const foiz = new Intl.NumberFormat("uz", {
style: "percent",
maximumFractionDigits: 1,
signDisplay: "exceptZero",
});
function ozgarishniYoz(eski, yangi) {
return foiz.format((yangi - eski) / eski);
}
console.log(ozgarishniYoz(35000, 40000)); // +14,3%
console.log(ozgarishniYoz(30000, 27000)); // -10%
console.log(ozgarishniYoz(5000, 5000)); // 0%(40000 - 35000) / 35000 ≈ 0.142857. percent uni 100 ga ko'paytirdi va bitta xonagacha yaxlitladi. -10% da kasr xona yo'q — maximumFractionDigits "ko'pi bilan" degani, keraksiz nol qo'shilmaydi.
3-mashq (qiyin): Og'irlik — har ikki muhitda bir xil
Yetkazib berish sahifasida og'irlik 2,5 kg ko'rinishida chiqishi kerak — Chrome'da ham. kgYoz(son) funksiyasini darsdagi somYoz uslubida yozing: formatToParts dan foydalaning, group ni uzilmas bo'sh joyga, decimal ni vergulga almashtiring, oxiriga kg qo'shing. Ko'pi bilan bitta kasr xona. 2.5, 1250 va 0.75 bilan sinang.
Yechim
const raqam = new Intl.NumberFormat("uz-UZ", {
maximumFractionDigits: 1,
});
const ALMASHTIR = { group: "\u00a0", decimal: "," };
function kgYoz(son) {
const matn = raqam
.formatToParts(son)
.map((b) => ALMASHTIR[b.type] ?? b.value)
.join("");
return `${matn} kg`;
}
console.log(kgYoz(2.5)); // 2,5 kg
console.log(kgYoz(1250)); // 1 250 kg
console.log(kgYoz(0.75)); // 0,8 kgALMASHTIR[b.type] ?? b.value — bo'lak turi lug'atda bo'lsa, o'rnini bosuvchi belgi olinadi, aks holda bo'lakning o'z qiymati. 0.75 bitta xonagacha 0,8 ga yaxlitlandi. if zanjiri o'rniga lug'at — switch va uning muqobillari darsidagi usul.
4-mashq: Vazifalar qadami — narx formati yordamchisi
vazifalar ilovasida narx yo'q, shuning uchun bu qadam mashqlar repozitoriysida. kurs/mashqlar/12/16-narx/narx.mjs faylida somYoz ni export qiling. Keyin shu papkada tekshir.mjs yarating: u somYoz ni import qilib, uchta narxni chiqarsin va natijada , yo'qligini includes bilan tekshirsin. Ikkala faylni Node 24 da ishga tushiring.
Yechim
narx.mjs:
const raqam = new Intl.NumberFormat("uz-UZ", {
maximumFractionDigits: 0,
});
export function somYoz(narx) {
const matn = raqam
.formatToParts(narx)
.map((b) => (b.type === "group" ? "\u00a0" : b.value))
.join("");
return `${matn} so'm`;
}tekshir.mjs:
import { somYoz } from "./narx.mjs";
for (const narx of [5000, 35000, 1250000]) {
const matn = somYoz(narx);
console.log(matn, matn.includes(",") ? "— vergul bor!" : "— toza");
}node tekshir.mjsKonsolda:
5 000 so'm — toza
35 000 so'm — toza
1 250 000 so'm — tozaBu tekshiruv kelajakdagi avtomatik testning birinchi qadami. node:test darsida uni assert bilan yozamiz.
git add 12/16-narx
git commit -m "12/16: somYoz — har brauzerda bir xil narx formati"12. Real ishda
- Onlayn do'kon va to'lov sahifalari. Savat, chek, to'lov tasdig'i — hamma joyda summa ko'rinadi. To'g'ri tartib: hisob tiyinda, butun son bilan; formatlash — faqat ekranga chiqarishda, bitta yordamchi funksiya orqali.
- Dashboardlar. Admin paneldagi "1,2 mln foydalanuvchi", "+14,3%" —
compactvasignDisplay. Chart.js kabi grafik kutubxonalari o'q yozuvlarini ichidaIntl.NumberFormatbilan formatlaydi va til kodini sozlama sifatida oladi. - Sinovlar va CI. Testlar odatda Node'da ishlaydi, mijoz esa narxni brauzerda ko'radi —
uzuchun natija farq qiladi. Jamoalar shuning uchun formatlashni bitta yordamchi funksiyaga yig'adi (somYozkabi) va faqat uni tekshiradi. - Intervyu. "Narxni turli valyuta va tillarda qanday ko'rsatasiz?", "Nega formatlangan narxni saqlamaslik kerak?" —
Intl.NumberFormat, tiyinda saqlash va formatlovchini keshlash haqida gapiring.
Xulosa
new Intl.NumberFormat(til, sozlamalar).format(son)— sonni til qoidalari bo'yicha matnga aylantiradi;toLocaleString— uning qisqa, lekin sekin shakli.- Valyuta:
style: "currency"+currency: "UZS"(ISO kodi majburiy); so'm uchunmaximumFractionDigits: 0. percentsonni 100 ga ko'paytiradi;signDisplay: "exceptZero"—+12%.- Yaxlitlash:
min/maximumFractionDigits,roundingMode,roundingIncrement: 500— faqat ekran uchun. notation: "compact"—1,5 mln;style: "unit"—2,5 kg;formatToPartsvaformatRange— bo'laklar va oraliq.- Formatlovchini bir marta yarating (o'lchovimizda ≈70 marta tez). Chrome 154 da
uzqoidalari yo'q (75,000) —formatToPartsbilan o'z ajratuvchingizni qo'ying.
Keyingi dars: Intl.PluralRules, ListFormat va DisplayNames — "1 day / 2 days" qoidalari qayerdan kelishini ko'ramiz, ro'yxatni "osh, manti va lag'mon" qilib yozamiz va davlat nomlarini har tilda olamiz.
Manbalar
- MDN: "Intl.NumberFormat", "Intl.NumberFormat() constructor" (barcha sozlamalar), "formatToParts", "formatRange" — developer.mozilla.org
- ECMA-402, "NumberFormat Objects" (roundingIncrement ruxsat etilgan qiymatlari) — tc39.es/ecma402
- ISO 4217 valyuta kodlari — iso.org; Unicode CLDR — cldr.unicode.org
- web-features 3.40:
formatRange,roundingIncrement,roundingMode— Baseline 2023-avgust
Izohlar (0)
Izoh yozish uchun kiring.
- Hozircha izoh yo'q. Birinchi bo'ling!