IlmHamroh
JavaScript Full-stack/12-qism. JavaScript: ilg'or mavzular va kod sifati13/44-dars21 daqiqa
Mundarija (46)

JavaScript Temporal API: Date o'rnini bosuvchi standart va sana kutubxonalari

Qisqacha: Temporal — Date o'rnini bosuvchi yangi standart (TC39'da 2026-yil martida 4-bosqichga yetdi). Unda har vazifa uchun alohida tur bor: PlainDate — faqat sana, PlainTime — faqat vaqt, Instant — aniq lahza, ZonedDateTime — lahza va zona, Duration — davomiylik. Obyektlari o'zgarmaydi, oylar 1 dan boshlanadi, "31-yanvar + 1 oy" esa 28-fevral beradi. Chrome 144+, Firefox 139+ da bor; Safari va Node 24 da yo'q — u yerda temporal-polyfill ishlatiladi. Eski loyihalarda date-fns, Day.js yoki Luxon uchraydi.

Bu darsda

  • Temporal nega kerakligini va Date ning qaysi muammolarini yechishini tushuntira olasiz.
  • Vazifaga qarab to'g'ri turni tanlaysiz: PlainDate, PlainTime, PlainDateTime, Instant, ZonedDateTime, Duration.
  • add, with, until, since, compare bilan sanalarni hisoblaysiz.
  • Temporal yo'q joyda temporal-polyfill ni ulaysiz va Date bilan Temporal o'rtasida o'tkazasiz.
  • date-fns, Day.js va Luxon'ni taniysiz va qachon qaysi biri kerakligini bilasiz.

Oldin bilishingiz kerak: Date asoslari, Date va vaqt zonalari, npm'ga birinchi qadam.

1. Nega bu kerak?

Oxirgi ikki darsda Sardor Date bilan ancha qiynaldi. Ro'yxatni eslaylik:

  • oylar 0 dan: new Date(2026, 9, 5) — oktabr;
  • setterlar sanani joyida o'zgartiradi, har safar new Date(sana) bilan nusxa kerak;
  • "31-yanvar + 1 oy" — 3-mart; to'g'ri oyQosh funksiyasi 10 qator bo'ldi;
  • "faqat sana" degan tur yo'q — "2026-10-05" UTC yarim tuniga aylanadi va Amerikada bir kunga siljiydi;
  • zona faqat ikkita: kompyuterniki va UTC; "Toshkent soati" uchun getUTCHours() + 5 hiylasi kerak bo'ldi.

Bu muammolarni yamash uchun 2010-yillarda kutubxonalar paydo bo'ldi — Moment.js, keyin date-fns, Day.js, Luxon. Ular yaxshi ishladi, lekin har loyihaga qo'shimcha kod yuklash kerak edi. 2017-yilda TC39 (JavaScript standartini yozadigan qo'mita) tilning o'ziga yangi sana API'sini qo'shishga kirishdi. U Temporal deb ataladi.

TC39'da har yangi taklif besh bosqichdan o'tadi: 0 — g'oya, 4 — "tayyor, standartga kiradi". Temporal ustida to'qqiz yil ishlandi. 2026-yil 12-martda u so'nggi, 4-bosqichga yetdi va ECMAScript 2027 ga kiradi. Bu — JavaScript tarixidagi eng katta qo'shimchalardan biri.

2. Temporal qayerda ishlaydi

2.1 Brauzerlar va Node

Holat 2026-yil oktabriga (Baseline ma'lumoti va o'zimiz sinaganimiz):

Muhit Temporal
Chrome, Edge 144-versiyadan bor (biz Chrome 154 da sinadik)
Firefox 139-versiyadan bor
Safari hali yo'q
Node 24 yo'q (faqat sinov uchun --harmony-temporal bayrog'i bilan)

Bayroq — Node'ni ishga tushirishda yoziladigan qo'shimcha sozlama (node --harmony-temporal fayl.mjs). Sinov bayrog'i bilan ishlaydigan narsaga real loyihada tayanilmaydi.

Hamma brauzerda hali yo'qligi uchun Temporal hozircha Baseline emas. Baseline — "barcha asosiy brauzerlarda ishlaydi" degan belgi, uni JS versiyalari va brauzer mosligi darsida to'liq ko'ramiz.

O'z muhitingizni bitta qator bilan tekshirasiz:

js
console.log(typeof Temporal);

Chrome 154 konsolida object chiqdi, Node 24 da — undefined.

Maslahat: Bu darsdagi Temporal misollari ostidagi «Ishga tushir» tugmasi kodni sizning brauzeringizda bajaradi. Chrome 144+ yoki Firefox 139+ da natija chiqadi, Safari'da esa ReferenceError: Temporal is not defined — bu ham darsning bir qismi. Har misol natijasini Chrome 154 da va Node 24 + temporal-polyfill da tekshirdik — ikkalasida bir xil chiqdi (farqlar alohida aytilgan).

2.2 Polyfill: Temporal yo'q joyda

Safari va Node uchun yechim — polyfill. O'rnatilgan prototiplar darsidan eslang: polyfill — yangi imkoniyatni eski muhitga JavaScript'ning o'zida yozib qo'shadigan kod.

Temporal uchun ikkita polyfill bor:

  • temporal-polyfill (1.0.5-versiya) — ixcham, README'siga ko'ra taxminan 20 kB (siqilgan holda), standartga to'liq mos;
  • @js-temporal/polyfill (0.5.1) — standart mualliflarining rasmiy polyfill'i, kattaroq va sekinroq.

Node loyihasida npm bilan o'rnatasiz:

bash
npm install temporal-polyfill@1.0.5

Keyin ikki usuldan birini tanlaysiz:

js
// 1-usul: o'zgaruvchi sifatida import qilish
import { Temporal } from "temporal-polyfill";

// 2-usul: global Temporal ni qo'shish (brauzerdagidek)
import "temporal-polyfill/global";

Birinchi usul xavfsizroq: kutubxona global obyektga tegmaydi. Ikkinchisi — kodni keyinchalik polyfill'siz ishlatishni rejalashtirsangiz qulay: brauzerlar Temporal'ni qo'llaganda faqat import qatorini o'chirasiz. Bu darsdagi misollar global Temporal bilan yozilgan.

Tekshirib ko'ring: Safari foydalanuvchilari ham ochadigan saytda Temporal.Now.plainDateISO() ni polyfill'siz yozsangiz nima bo'ladi?

Javob

Chrome va Firefox'da ishlaydi, Safari'da esa ReferenceError: Temporal is not defined chiqadi va skript to'xtaydi. Hamma brauzerda Temporal paydo bo'lguncha polyfill yoki "bor bo'lsa — ishlat" tekshiruvi kerak.

3. Temporal turlari: har vazifaga — o'z turi

3.1 Turlar xaritasi

Date bitta tur bilan hamma narsani qilishga urinadi. Temporal esa savolga qarab turni tanlashni so'raydi: sizga lahza kerakmi yoki devor kalendari va soati?

flowchart TD
  S{"Sizga nima kerak?"} -->|"aniq lahza (log, buyurtma)"| I["Instant"]
  S -->|"lahza + zona"| Z["ZonedDateTime"]
  S -->|"kalendar va soat, zonasiz"| P{"Qaysi qismi?"}
  P -->|"sana + vaqt"| PDT["PlainDateTime"]
  P -->|"faqat sana"| PD["PlainDate"]
  P -->|"faqat vaqt"| PT["PlainTime"]
  S -->|"qancha davom etadi"| D["Duration"]

Diagrammadan qanday foydalanish: Sardorning har vazifasi uchun yuqoridan savol bering. "Buyurtma qachon kelgan?" — aniq lahza, Instant. "Toshkentda soat nechada kelgan?" — lahza va zona, ZonedDateTime. "Bron qaysi kunga?" — faqat sana, PlainDate. "«Bahor» soat nechada ochiladi?" — faqat vaqt, PlainTime. "Bron qancha davom etadi?" — Duration.

Plain ("oddiy, yalang'och") — zonasiz degani. Devordagi kalendar varag'i yoki soat kabi: "5-oktabr" va "07:00" — lekin qaysi shaharda ekani aytilmagan.

3.2 Uchta umumiy qoida

Turlarga o'tishdan oldin — hamma turga tegishli uchta qoida. Ular Date ning uchta katta muammosini yechadi.

  1. O'zgarmaslik. Temporal obyekti hech qachon o'zgarmaydi. add, with kabi metodlar yangi obyekt qaytaradi. Nusxa olishni unutish xatosi yo'qoladi.
  2. Oylar 1 dan. Oktabr — 10. Hafta kuni ham odatdagidek: dushanba — 1, yakshanba — 7.
  3. Qat'iy o'qish. Faqat ISO 8601 matn qabul qilinadi. Noto'g'ri qiymat — darhol RangeError, jim Invalid Date emas.

Obyekt yaratish — new bilan emas, odatda from statik metodi bilan. Matnga aylantirish — toString().

O'zingiz to'ldiring: Temporal'da oktabr oyining raqami — (Date da u 9 edi).

4. PlainDate — faqat sana

4.1 Yaratish va qismlar

js
const bron = Temporal.PlainDate.from("2026-10-05");

console.log(bron.toString()); // 2026-10-05
console.log(bron.year, bron.month, bron.day); // 2026 10 5
console.log(bron.dayOfWeek); // 1
console.log(bron.daysInMonth); // 31
console.log(bron.inLeapYear); // false

Qismlar — metod emas, xususiyat: getMonth() o'rniga month. Oy — 10, oktabr. dayOfWeek — 1, dushanba. daysInMonth — oyda nechta kun: "0-kun" hiylasi endi kerak emas.

PlainDate da soat ham, zona ham yo'q. Shuning uchun "Nyu-Yorkda bir kunga siljish" muammosi bu turda bo'lishi mumkin emas: 5-oktabr hamma joyda 5-oktabr.

Obyektdan ham yaratish mumkin:

js
const navroz = Temporal.PlainDate.from({
  year: 2027, month: 3, day: 21,
});

console.log(navroz.toString()); // 2027-03-21
console.log(navroz.dayOfWeek); // 7

2027-yil Navro'zi — yakshanba (7).

4.2 add va with — yangi sana qaytaradi

Date asoslari darsidagi obuna masalasini eslang — 31-yanvarga bir oy qo'shish:

js
const tolov = Temporal.PlainDate.from("2026-01-31");
const keyingi = tolov.add({ months: 1 });

console.log(keyingi.toString()); // 2026-02-28
console.log(tolov.toString()); // 2026-01-31

Bir qator. 31-fevral yo'q, shuning uchun Temporal kunni oyning oxiriga "qisdi" — 28-fevral. Asl tolov o'zgarmadi. Date da 10 qator yozgan edik.

Bu xulq overflow sozlamasi bilan boshqariladi. Sukut bo'yicha — "constrain" ("chegarala"). Qisish xato deb hisoblansin desangiz — "reject":

js
const tolov = Temporal.PlainDate.from("2026-01-31");
tolov.add({ months: 1 }, { overflow: "reject" });

Bu blok ataylab xato beradi. Chrome 154 konsolida:

text
RangeError: Temporal error: not a valid ISO date.

Tarjimasi: "Temporal xatosi: yaroqli ISO sana emas." 31-fevral — mavjud bo'lmagan sana, "reject" esa uni qisishni taqiqladi. Xabar matni muhitga bog'liq: temporal-polyfill bir xil holatda Invalid day: 31; must be between 1-28 ("kun 1–28 oralig'ida bo'lishi kerak") deydi. Xato turi — RangeError — ikkalasida bir xil.

with — bir qismini almashtirib, yangi sana:

js
const bron = Temporal.PlainDate.from("2026-10-05");

console.log(bron.with({ day: 1 }).toString()); // 2026-10-01
console.log(bron.add({ days: 30 }).toString()); // 2026-11-04

4.3 Qat'iy o'qish

js
Temporal.PlainDate.from("2026-02-30");

Chrome 154 konsolida:

text
RangeError: Temporal error: Parsed day value not in a valid range.

Tarjimasi: "O'qilgan kun qiymati yaroqli oraliqda emas." Matndan o'qishda overflow ishlamaydi — matn doim qat'iy tekshiriladi. Date bu matnni jim 2-martga aylantirgan edi.

Tekshirib ko'ring: Temporal.PlainDate.from("2026-03-31").add({ months: 1 }) qaysi sana?

Javob

2026-04-30. Aprelda 30 kun bor, 31-aprel yo'q — sukut bo'yicha "constrain" kunni oy oxiriga qisadi.

5. Solishtirish va farq

5.1 equals va compare

js
const a = Temporal.PlainDate.from("2026-10-05");
const b = Temporal.PlainDate.from("2026-10-12");

console.log(a.equals(Temporal.PlainDate.from("2026-10-05"))); // true
console.log(Temporal.PlainDate.compare(a, b)); // -1
console.log([b, a].sort(Temporal.PlainDate.compare).join(", "));
// 2026-10-05, 2026-10-12

equals — "bir xil sanami?". compare — statik metod, -1, 0 yoki 1 qaytaradi. U aynan sort kutgan shaklda, shuning uchun to'g'ridan-to'g'ri sort ga beriladi.

< va > esa Temporal'da ishlamaydi — ataylab:

js
const a = Temporal.PlainDate.from("2026-10-05");
console.log(a < Temporal.PlainDate.from("2026-10-12"));

Chrome 154 konsolida:

text
TypeError: Do not use Temporal.PlainDate.prototype.valueOf; use Temporal.PlainDate.prototype.compare for comparison.

Tarjimasi: "valueOf ni ishlatmang; solishtirish uchun compare ni ishlating." < obyektni songa aylantirmoqchi bo'ladi (coercion darsidagi valueOf). Temporal'da valueOf ataylab xato tashlaydi. Sabab: turli turdagi obyektlarni (masalan, sana va lahzani) jim solishtirib qo'yish xatosini oldini olish.

5.2 until va since — farq Duration bo'lib keladi

js
const bugun = Temporal.PlainDate.from("2026-10-05");
const bronKuni = Temporal.PlainDate.from("2026-10-12");
const farq = bugun.until(bronKuni);

console.log(farq.toString()); // P7D
console.log(farq.days); // 7

O'tgan darsdagi kunlarFarqi — Date.UTC, Math.round va 10 qator — endi bitta until. Natija son emas, Duration obyekti. P7D — uning ISO yozuvi: P ("period") — davomiylik boshlanishi, 7D — 7 kun.

Farqni qaysi birlikda olishni largestUnit belgilaydi:

js
const bugun = Temporal.PlainDate.from("2026-10-05");
const yangiYil = Temporal.PlainDate.from("2026-12-25");

console.log(bugun.until(yangiYil).toString()); // P81D
console.log(
  bugun.until(yangiYil, { largestUnit: "months" }).toString(),
); // P2M20D

Sukut bo'yicha sanalar orasidagi farq kunlarda — P81D. largestUnit: "months" bilan — 2 oy va 20 kun. since — until ning teskarisi: yangiYil.since(bugun) ham P81D.

Tekshirib ko'ring: Temporal.PlainDate.from("2026-10-12").until("2026-10-05").days nechchi?

Javob

-7. until "shu sanadan o'sha sanagacha" deb hisoblaydi; o'sha sana oldinda bo'lsa, natija manfiy. E'tibor bering: until ga matn ham berish mumkin — u o'zi PlainDate.from qiladi.

6. PlainTime va Duration — «Bahor» ish vaqti

6.1 Faqat vaqt

«Bahor» ochilishi va yopilishi — sana bilan bog'liq emas, har kuni bir xil. Bu — aniq PlainTime:

js
const ochilish = Temporal.PlainTime.from("07:00");
const yopilish = Temporal.PlainTime.from("23:00");
const ishVaqti = ochilish.until(yopilish);

console.log(ishVaqti.toString()); // PT16H
console.log(ishVaqti.total("minutes")); // 960

PT16H — "16 soat" (T — vaqt qismi boshlanishi). total("minutes") — butun davomiylikni bitta birlikka aylantiradi: 960 daqiqa.

Bron 10:00 dan 22:00 gacha qabul qilinadi. Tekshiruv compare bilan:

js
const BRON_BOSHI = Temporal.PlainTime.from("10:00");
const BRON_OXIRI = Temporal.PlainTime.from("22:00");

function bronMumkinmi(vaqt) {
  const v = Temporal.PlainTime.from(vaqt);
  return Temporal.PlainTime.compare(v, BRON_BOSHI) >= 0
    && Temporal.PlainTime.compare(v, BRON_OXIRI) <= 0;
}

console.log(bronMumkinmi("09:59")); // false
console.log(bronMumkinmi("22:00")); // true
console.log(bronMumkinmi("22:01")); // false

Date dagi "soatni 60 ga ko'paytirib, daqiqani qo'shish" hiylasi kerak emas. <input type="time"> qiymati ("19:30") to'g'ridan-to'g'ri from ga beriladi.

Vaqt aylana bo'ylab yuradi: Temporal.PlainTime.from("22:30").add({ hours: 2 }) — 00:30:00. Sana yo'q, shuning uchun "ertasi kun" ham yo'q.

6.2 Duration bilan ishlash

js
const bron = Temporal.Duration.from({ hours: 1, minutes: 30 });

console.log(bron.toString()); // PT1H30M
console.log(bron.total("minutes")); // 90

const xom = Temporal.Duration.from({ minutes: 150 });
console.log(xom.toString()); // PT150M
const yigilgan = xom.round({ largestUnit: "hours" });
console.log(yigilgan.toString()); // PT2H30M

Duration o'zi "150 daqiqa" ni "2 soat 30 daqiqa" ga aylantirmaydi — siz so'ramaguningizcha. round({ largestUnit: "hours" }) — "soatgacha yig'ib chiq". Davomiylikni odam tilida chiqarish uchun Intl.DurationFormat bor: Node 24 da new Intl.DurationFormat("uz", { style: "long" }).format({ hours: 2, minutes: 30 }) — 2 soat 30 daqiqa. Chrome 154 da esa o'zbekcha ma'lumot yo'q va 2 hours, 30 minutes chiqadi (brauzer tili ruscha bo'lsa — 2 часа, 30 минуты) — bu muammoni keyingi darsda ko'ramiz.

Tekshirib ko'ring: Temporal.PlainTime.from("07:00").until("23:00").hours nechchi?

Javob

16. until natijasi — PT16H, uning hours xususiyati 16. minutes esa 0: davomiylik 16 soat va 0 daqiqa deb saqlangan.

7. Instant va ZonedDateTime — lahza va zona

7.1 Instant — aniq lahza

Instant — Date ning eng yaqin qarindoshi: zonasiz, kalendarsiz lahza.

js
const buyurtma = Temporal.Instant.from("2026-10-05T12:00:00Z");

console.log(buyurtma.toString()); // 2026-10-05T12:00:00Z
console.log(buyurtma.epochMilliseconds); // 1791201600000

epochMilliseconds — o'sha tanish timestamp. Instant matni albatta Z yoki offset bilan bo'lishi kerak. Offset'siz "2026-10-05T12:00" bersangiz — RangeError (Chrome: Required fields missing from Instant string — "Instant matnida majburiy maydonlar yo'q"). Date ning "qaysi zonada o'qiyman?" degan chalkashligi shu bilan yo'qoladi.

7.2 ZonedDateTime — Toshkentda soat nechchi?

Lahzani zonaga "kiygizamiz":

js
const buyurtma = Temporal.Instant.from("2026-10-05T12:00:00Z");
const toshkentda = buyurtma.toZonedDateTimeISO("Asia/Tashkent");

console.log(toshkentda.toString());
// 2026-10-05T17:00:00+05:00[Asia/Tashkent]
console.log(toshkentda.hour); // 17
console.log(toshkentda.offset); // +05:00

const moskvada = toshkentda.withTimeZone("Europe/Moscow");
console.log(moskvada.hour); // 15

ZonedDateTime matni ISO'dan biroz uzunroq: oxirida kvadrat qavsda zona nomi. Bu kengaytma RFC 9557 da belgilangan — RFC internet standartlari hujjatlarining nomi. Matnda offset ham, zona ham bor — o'qigan dastur lahzani ham, qoidalarni ham biladi.

O'tgan darsdagi Moskva muammosi endi hiylasiz yechiladi, va istalgan zona uchun — DST bor zonalar uchun ham:

js
function ochiqmi(lahza) {
  const soat = lahza.toZonedDateTimeISO("Asia/Tashkent").hour;
  return soat >= 7 && soat < 23;
}

console.log(ochiqmi(Temporal.Instant.from("2026-10-05T19:30:00Z")));
// false

UTC 19:30 — Toshkentda 00:30, «Bahor» yopiq. Mehmon kompyuteri qaysi zonada bo'lishi ahamiyatsiz.

7.3 Forma vaqtidan lahzaga

<input type="datetime-local"> qiymati (2026-10-05T19:30) — zonasiz sana-vaqt, ya'ni PlainDateTime. «Bahor» Toshkentda, shuning uchun unga Toshkent zonasini biriktiramiz:

js
const formadan = Temporal.PlainDateTime.from("2026-10-05T19:30");
const bron = formadan.toZonedDateTime("Asia/Tashkent");

console.log(bron.toString());
// 2026-10-05T19:30:00+05:00[Asia/Tashkent]
console.log(bron.toInstant().toString()); // 2026-10-05T14:30:00Z

Endi serverga yuboriladigan narsa aniq: 2026-10-05T14:30:00Z — UTC'dagi lahza. Son, sana, vaqt va rang maydonlari darsidagi "Germaniyadagi server 19:30 ni noto'g'ri tushundi" muammosi shu ikki qator bilan yo'qoladi.

7.4 DST endi tuzoq emas

O'tgan darsda Berlinda "1 kun qo'shish" va "24 soat qo'shish" farqini ko'rish uchun kompyuter zonasini o'zgartirgandik. ZonedDateTime bilan zona kod ichida:

js
const berlin = Temporal.ZonedDateTime.from(
  "2026-03-28T10:00[Europe/Berlin]",
);

console.log(berlin.add({ days: 1 }).toString());
// 2026-03-29T10:00:00+02:00[Europe/Berlin]
console.log(berlin.add({ hours: 24 }).toString());
// 2026-03-29T11:00:00+02:00[Europe/Berlin]

const kun = Temporal.ZonedDateTime.from(
  "2026-03-29T12:00[Europe/Berlin]",
);
console.log(kun.hoursInDay); // 23

days: 1 — kalendar kuni, hours: 24 — aniq 24 soat; Temporal ikkalasini to'g'ri ajratadi. hoursInDay — shu kun necha soat davom etishi: DST kuni 23. Toshkent uchun u doim 24.

7.5 Date ↔ Temporal

Eski kod Date bilan yozilgan bo'ladi. O'tish ikki yo'nalishda:

js
const eski = new Date("2026-10-05T12:00:00Z");
const lahza = eski.toTemporalInstant();
console.log(lahza.toString()); // 2026-10-05T12:00:00Z

const qaytib = new Date(lahza.epochMilliseconds);
console.log(qaytib.toISOString()); // 2026-10-05T12:00:00.000Z

toTemporalInstant — Date ga qo'shilgan yangi metod (polyfill'ning global varianti ham uni qo'shadi). Yo'q joyda — Temporal.Instant.fromEpochMilliseconds(eski.getTime()). Orqaga — timestamp orqali.

JSON.stringify Temporal obyektlarini ISO matnga aylantiradi: {"sana":"2026-10-05"}. O'qishda esa from kerak — JSON chuqur darsidagi reviver yordam beradi.

Tekshirib ko'ring: Log faylga yoziladigan "xato qachon chiqdi" vaqti uchun qaysi tur to'g'ri: PlainDateTime yoki Instant?

Javob

Instant. Log — aniq lahza, uni dunyoning istalgan joyida bir ma'noda tushunish kerak. PlainDateTime da zona yo'q — "19:30" qaysi shahar soati ekanini bilib bo'lmaydi.

8. Temporal va Intl

Temporal obyektlarida ham toLocaleString bor — u keyingi darsdagi Intl.DateTimeFormat ni ishlatadi:

js
const sana = Temporal.PlainDate.from("2026-10-05");

console.log(sana.toLocaleString("ru", { dateStyle: "long" }));
console.log(sana.toLocaleString("en", { dateStyle: "long" }));
console.log(sana.toLocaleString("uz", { dateStyle: "long" }));

Chrome 154 konsolida:

text
5 октября 2026 г.
October 5, 2026
2026 M10 5

Ruscha va inglizcha — to'g'ri. O'zbekchada esa 2026 M10 5 — Chrome'da o'zbek oy nomlari yo'q! Node 24 + polyfill'da xuddi shu qator 5-oktabr, 2026 beradi. Nega va nima qilish kerak — Intl.DateTimeFormat darsining asosiy mavzularidan biri.

9. Sana kutubxonalari

Temporal hamma joyda paydo bo'lguncha va undan keyin ham ko'p yillar davomida siz kutubxonali kodni uchratasiz. To'rttasini tanib olish kerak. Quyidagi natijalar Node 24 da, aniq versiyalar bilan haqiqatan ishga tushirilgan.

9.1 date-fns — funksiyalar to'plami

date-fns (4.4.0) — oddiy Date ustida ishlaydigan 200 dan ortiq alohida funksiya. Ular asl sanani o'zgartirmaydi, yangisini qaytaradi:

js
import {
  addMonths, format, differenceInCalendarDays,
} from "date-fns";
import { uz } from "date-fns/locale";

const yanvar31 = new Date(2026, 0, 31);
console.log(addMonths(yanvar31, 1).getDate()); // 28

const sana = new Date(2026, 9, 5, 17, 0);
console.log(format(sana, "dd.MM.yyyy HH:mm")); // 05.10.2026 17:00
console.log(format(sana, "d-MMMM, yyyy", { locale: uz }));
// 5-Oktabr, 2026

const bugun = new Date(2026, 9, 5, 21, 40);
const bron = new Date(2026, 9, 12, 10, 0);
console.log(differenceInCalendarDays(bron, bugun)); // 7

Afzalligi — faqat ishlatgan funksiyangiz loyihaga qo'shiladi. O'zbek tili ma'lumotlari kutubxonaning o'zida keladi, shuning uchun brauzerga bog'liq emas. E'tibor bering: unda oy nomi katta harf bilan — Oktabr. Zonalar uchun alohida @date-fns/tz (1.5.0) paketi bor.

9.2 Day.js — kichik va zanjirli

Day.js (1.11.23) — Moment.js uslubidagi API, lekin juda kichik. Obyektlari o'zgarmaydi, metodlar zanjir bo'lib ulanadi:

js
import dayjs from "dayjs";

const tolov = dayjs("2026-01-31");
console.log(tolov.add(1, "month").format("YYYY-MM-DD")); // 2026-02-28
const bron = dayjs("2026-10-12");
console.log(bron.diff(dayjs("2026-10-05"), "day")); // 7
console.log(dayjs("2026-10-05").format("YYYY-MM-DD HH:mm"));
// 2026-10-05 00:00

Oxirgi qatorga qarang: Day.js "2026-10-05" ni mahalliy yarim tun deb o'qidi — Date dan farqli. Bitta matn har kutubxonada boshqacha tushunilishi mumkin; hujjatni o'qing. Zonalar utc va timezone plaginlari bilan qo'shiladi. Plagin — kutubxonaga alohida ulanadigan qo'shimcha bo'lak: kerak bo'lsa ulaysiz, bo'lmasa hajm oshmaydi.

9.3 Luxon — zona bilan ishlash uchun

Luxon (3.7.2) — Moment.js jamoasi a'zosi yozgan kutubxona. Asosiy klassi DateTime — Temporal'dagi ZonedDateTime ga o'xshaydi:

js
import { DateTime } from "luxon";

const lahza = DateTime.fromISO("2026-10-05T12:00:00Z", {
  zone: "Asia/Tashkent",
});
console.log(lahza.toISO()); // 2026-10-05T17:00:00.000+05:00
console.log(lahza.hour); // 17
console.log(lahza.setLocale("ru").toLocaleString(DateTime.DATE_FULL));
// 5 октября 2026 г.

Luxon tarjimalarni brauzerning Intl idan oladi — shuning uchun o'zbekcha bilan Chrome'da xuddi Temporal'dagi muammo bo'ladi.

9.4 Moment.js — faqat eski kodda

Moment.js — 2010-yillarning eng mashhur sana kutubxonasi. 2020-yil sentabrida uning jamoasi loyihani "tugallangan" deb e'lon qildi: yangi imkoniyat qo'shilmaydi, faqat xavfsizlik tuzatishlari. Ular o'zlari yangi loyihalarda boshqa kutubxona tanlashni tavsiya qiladi. Sabablari: obyektlari o'zgaruvchan va katta hajm.

Eski loyihada moment() ni ko'rsangiz — o'qiy olasiz: moment("2026-01-31").add(1, "month"). Lekin yangi kodga qo'shmang.

9.5 Hajm: brauzerga qancha kod yuklanadi

Saytga kutubxona qo'shsangiz, uni har bir mehmon yuklab oladi. Biz har kutubxonada bitta xil ishni — "bugunga bir oy qo'shib, chiqarish" — yozib, haqiqiy bundle hajmini o'lchadik. Bundle — saytga yuklanadigan, barcha import'lar bitta faylga yig'ilgan JavaScript. Uni yasaydigan vositalarni (bundler) 16-qismda o'rganamiz, hozir faqat hajmiga qarang:

Bir oy qo'shish uchun yuklanadigan kod (siqilgan)
  • Temporal (brauzerda bor)Chrome 144+, Firefox 139+0 kB
  • Day.js 1.11.233,4 kB
  • date-fns 4.4.0faqat 2 funksiya5,8 kB
  • temporal-polyfill 1.0.519,7 kB
  • Moment.js 2.31.020,6 kB
  • Luxon 3.7.221,9 kB

Manba: O'lchandi 2026-10-05: esbuild 0.25.12 --bundle --minify, gzip -9; har kutubxonada bitta import va bitta amal

Ustunlarga qarang: o'rnatilgan Temporal — nol kod. Day.js va date-fns — eng kichiklari. Temporal polyfill'i Moment va Luxon bilan bir og'irlikda, lekin u vaqtinchalik: brauzerlar Temporal'ni qo'llagach, uni olib tashlaysiz.

9.6 Qaysini tanlash kerak

Vaziyat Tanlov
Yangi loyiha, faqat zamonaviy brauzerlar Temporal
Yangi loyiha, Safari ham kerak Temporal + temporal-polyfill
Date li mavjud loyiha, bir nechta amal date-fns
Hajm juda muhim, Moment uslubi tanish Day.js
Ko'p zona, xalqaro jadval Temporal yoki Luxon

Yagona qat'iy qoida: bitta loyihada bitta sana vositasi. Uchta kutubxona aralashgan kodda har biri sanani o'zicha o'qiydi.

10. Ko'p uchraydigan xatolar

10.1 Temporal hamma joyda bor deb o'ylash

Chrome'da ishlagan sayt Safari'da ReferenceError: Temporal is not defined beradi. Tuzatish: polyfill ulang yoki mavjudligini tekshiring (typeof Temporal !== "undefined").

10.2 Noto'g'ri tur

Bron kunini ZonedDateTime yoki Instant da saqlash — zona o'zgarganda kun siljiydi. Ochilish vaqtini PlainDateTime da saqlash — keraksiz sana. Tuzatish: diagrammadagi savolni bering: "lahzami yoki devor kalendarimi?".

10.3 Natijani saqlamaslik

js
const bron = Temporal.PlainDate.from("2026-10-05");
bron.add({ days: 1 });
console.log(bron.toString()); // 2026-10-05

Date dan o'tganlar setter kabi yozadi va natija "o'zgarmaganiga" hayron bo'ladi. add yangi obyekt qaytardi — u esa hech qayerga saqlanmadi. Tuzatish: const ertaga = bron.add({ days: 1 });.

10.4 < va === bilan solishtirish

< — TypeError, === — ikki xil obyekt uchun doim false. Tuzatish: Temporal.PlainDate.compare(a, b) va a.equals(b).

10.5 Kutubxonalarni aralashtirish

date-fns Date qaytaradi, Day.js — o'z obyektini, Temporal — o'zinikini. Ularni bir-biriga uzatganda kutilmagan natija chiqadi. Tuzatish: chegarada aniq o'tkazing — ISO matn yoki timestamp orqali.

11. Mashqlar

1-mashq (oson): Ish vaqti necha daqiqa?

ishDaqiqalari(ochilish, yopilish) — ikki "HH:MM" matn oladi va oradagi daqiqalarni son qilib qaytarsin. Ishora: PlainTime.from, until, total("minutes").

js
console.log(ishDaqiqalari("07:00", "23:00")); // 960
console.log(ishDaqiqalari("10:00", "22:00")); // 720
Yechim
js
function ishDaqiqalari(ochilish, yopilish) {
  const boshi = Temporal.PlainTime.from(ochilish);
  return boshi.until(yopilish).total("minutes");
}

console.log(ishDaqiqalari("07:00", "23:00")); // 960
console.log(ishDaqiqalari("10:00", "22:00")); // 720

until ga matn berish mumkin — u o'zi PlainTime ga aylantiradi. total davomiylikni bitta birlikdagi songa aylantiradi.

2-mashq (o'rta): Obuna jadvali

tolovlarJadvali(boshlanish, soni) — birinchi to'lov kunidan boshlab soni ta oylik to'lov sanalarini matnlar massivi qilib qaytarsin. Har sana birinchi sanaga { months: i } qo'shib hisoblansin, oldingisiga emas. Ishora: Array.from va add.

js
console.log(tolovlarJadvali("2026-01-31", 4));
// [ '2026-01-31', '2026-02-28', '2026-03-31', '2026-04-30' ]
Yechim
js
function tolovlarJadvali(boshlanish, soni) {
  const birinchi = Temporal.PlainDate.from(boshlanish);
  return Array.from({ length: soni }, (_, i) =>
    birinchi.add({ months: i }).toString(),
  );
}

console.log(tolovlarJadvali("2026-01-31", 4));

Konsolda:

text
[ '2026-01-31', '2026-02-28', '2026-03-31', '2026-04-30' ]

Nega birinchi sanadan? Oldingisiga qo'shsak, 28-fevraldan keyin 28-mart, 28-aprel bo'lardi — mehmon har oy uch kun "yo'qotardi". Har safar asl 31-dan hisoblaganda Temporal faqat qisqa oyda kunni qisadi, keyingi oyda yana 31-ga qaytadi.

3-mashq (qiyin): Buyurtma Toshkentda qaysi kunga tegishli?

Server buyurtmalarni UTC lahzalar ro'yxati sifatida beradi. kunlarBoyicha(lahzalar) — ularni Toshkent kunlari bo'yicha guruhlab, { "YYYY-MM-DD": soni } obyektini qaytarsin. Ishora: Instant.from, toZonedDateTimeISO("Asia/Tashkent"), toPlainDate() (ZonedDateTime'dan faqat sanani oladi).

js
const lahzalar = [
  "2026-10-05T03:00:00Z",
  "2026-10-05T18:30:00Z",
  "2026-10-05T19:30:00Z",
];
console.log(kunlarBoyicha(lahzalar));
// { '2026-10-05': 2, '2026-10-06': 1 }
Yechim
js
function kunlarBoyicha(lahzalar) {
  const natija = {};
  for (const matn of lahzalar) {
    const kun = Temporal.Instant.from(matn)
      .toZonedDateTimeISO("Asia/Tashkent")
      .toPlainDate()
      .toString();
    natija[kun] = (natija[kun] ?? 0) + 1;
  }
  return natija;
}

const lahzalar = [
  "2026-10-05T03:00:00Z",
  "2026-10-05T18:30:00Z",
  "2026-10-05T19:30:00Z",
];
console.log(kunlarBoyicha(lahzalar));

Konsolda:

text
{ '2026-10-05': 2, '2026-10-06': 1 }

UTC bo'yicha uchalasi ham 5-oktabr. Toshkentda esa 18:30 → 23:30 (hali 5-oktabr), 19:30 → 00:30 (6-oktabr). Zanjir to'rt qadam: matn → lahza → Toshkentdagi lahza → kalendar kuni → matn.

4-mashq: Vazifalar qadami — polyfill bilan Node'da

vazifalar kodiga yangi paket qo'shmaymiz — u brauzerda paketsiz ishlaydi. Temporal'ni Node'da sinab ko'ramiz. kurs/mashqlar/12/13-temporal/ papkasida npm init -y va npm install temporal-polyfill@1.0.5 qiling. muddat.mjs faylida o'tgan darsdagi 4-mashqni Temporal bilan qayta yozing: muddati o'tgan va bugungi vazifalarni chiqaring.

js
const bugun = "2026-10-05";
const vazifalar = [
  { matn: "Non olish", muddat: "2026-10-05" },
  { matn: "Kommunal to'lov", muddat: "2026-10-03" },
  { matn: "Kitob qaytarish", muddat: "2026-10-09" },
];
Yechim
js
import { Temporal } from "temporal-polyfill";

const bugun = Temporal.PlainDate.from("2026-10-05");
const vazifalar = [
  { matn: "Non olish", muddat: "2026-10-05" },
  { matn: "Kommunal to'lov", muddat: "2026-10-03" },
  { matn: "Kitob qaytarish", muddat: "2026-10-09" },
];

for (const vazifa of vazifalar) {
  const qoldi = bugun.until(vazifa.muddat).days;
  if (qoldi < 0) {
    console.log(`MUDDATI O'TGAN (${-qoldi} kun): ${vazifa.matn}`);
  } else if (qoldi === 0) {
    console.log(`BUGUN: ${vazifa.matn}`);
  }
}

Konsolda (node 12/13-temporal/muddat.mjs):

text
BUGUN: Non olish
MUDDATI O'TGAN (2 kun): Kommunal to'lov

O'tgan darsda sananiOqi va kunlarFarqi — 15 qator edi. Bu yerda until muddat matnini o'zi o'qiydi va soatsiz kunlarni beradi. node_modules ni git'ga qo'shmang — .gitignore ga yozing (npm'ga birinchi qadam).

bash
git add 12/13-temporal/package.json 12/13-temporal/package-lock.json
git add 12/13-temporal/muddat.mjs
git commit -m "12/13: muddatlarni Temporal PlainDate bilan hisobla"

12. Real ishda

  • Hozirgi kod bazalari. 2026-yilda ishga kirsangiz, ko'p loyihada date-fns yoki Day.js, eskilarida Moment.js uchraydi. Temporal — yangi loyihalarda va bosqichma-bosqich ko'chishda.
  • Kalendar va bron tizimlari. Taksi buyurtmasi, shifokor qabuli, aviachipta — PlainDate/PlainTime (foydalanuvchi tanlagani) va Instant (saqlangani) farqi aynan shu yerda muhim.
  • Server. Node'ning yangi versiyalarida Temporal V8 yangilanishi bilan paydo bo'lishi kutiladi — o'z versiyangizni typeof Temporal bilan tekshiring; ungacha temporal-polyfill. Bazaga — ISO matn yoki timestamp.
  • Intervyu. "Date ning qanday muammolarini bilasiz?", "Temporal'da PlainDate va ZonedDateTime farqi?", "Nega Moment.js'dan voz kechildi?" — tez-tez so'raladi.

Xulosa

  • Temporal — Date o'rnini bosuvchi standart: o'zgarmas obyektlar, oylar 1 dan, qat'iy ISO o'qish; TC39 4-bosqich (2026-mart), ES2027.
  • Turni savol bo'yicha tanlang: lahza — Instant, lahza + zona — ZonedDateTime, devor kalendari — PlainDate / PlainTime / PlainDateTime, davomiylik — Duration.
  • add, with — yangi obyekt; until/since — Duration; compare/equals — solishtirish (< ishlamaydi).
  • Chrome/Edge 144+, Firefox 139+ — bor; Safari va Node 24 — yo'q, temporal-polyfill@1.0.5 bilan.
  • Kutubxonalar: date-fns — funksiyalar, Day.js — kichik, Luxon — zonalar; Moment.js — faqat eski kodda.

Keyingi dars: Intl.DateTimeFormat — sanani mehmon tilida va kerakli zonada chiroyli chiqarish, formatToParts, formatRange va Chrome'dagi o'zbekcha "2026 M10 5" muammosini yechish.

Manbalar

  • MDN: "Temporal", "Temporal.PlainDate", "Temporal.ZonedDateTime", "Temporal.Duration" — developer.mozilla.org
  • TC39 Temporal taklifi va hujjatlari — tc39.es/proposal-temporal/docs
  • Igalia Chats: "Temporal Stage 4" (2026-03-13) — igalia.com/chats/temporal-stage-4
  • web-features 3.40.0 — temporal (Chrome 144, Firefox 139)
  • temporal-polyfill (1.0.5), date-fns (4.4.0), Day.js (1.11.23), Luxon (3.7.2) — npmjs.com; Moment.js "Project Status" — momentjs.com/docs
Ulashish:Telegram'da

Izohlar (0)

Izoh yozish uchun kiring.

  • Hozircha izoh yo'q. Birinchi bo'ling!
JavaScript Temporal API: Date o'rnini bosuvchi standart va sana kutubxonalari — IlmHamroh