Mundarija (41)
- Bu darsda
- 1. Nega bu kerak?
- 2. UTC, offset va vaqt zonasi
- 2.1 Bitta lahza — ko'p soat
- 2.2 Vaqt zonasi — offset'dan ko'proq
- 2.3 Kompyuteringiz qaysi zonada?
- 2.4 getTimezoneOffset — teskari ishora
- 3. Mahalliy va UTC getterlar
- 3.1 Ikki to'plam
- 3.2 Date.UTC — UTC'da qismlardan yaratish
- 3.3 «Bahor» Toshkent soati bilan
- 4. ISO 8601 — sanani matnda yozish standarti
- 4.1 Tuzilishi
- 4.2 toISOString — doim UTC
- 4.3 Offset'li matnni o'qish
- 5. Matn qanday o'qiladi: eng katta tuzoq
- 5.1 Faqat sana — UTC, sana va vaqt — mahalliy
- 5.2 Nyu-Yorkdagi "4-oktabr"
- 5.3 datetime-local qiymati
- 5.4 ISO bo'lmagan matnlar — dvigatelga bog'liq
- 6. Yozgi vaqt (DST): kun har doim 24 soat emas
- 6.1 Nima u
- 6.2 "24 soat qo'shish" va "1 kun qo'shish" — har xil
- 7. Farqni hisoblash va taqqoslash
- 7.1 Kunlar farqi — Date.UTC bilan
- 7.2 Bir kunmi?
- 7.3 Saralash va eng kech sana
- 8. Ko'p uchraydigan xatolar
- 8.1 "Bugungi sana" uchun toISOString().slice(0, 10)
- 8.2 new Date("YYYY-MM-DD") bilan sana o'qish
- 8.3 Offset'ni zona deb saqlash
- 8.4 getTimezoneOffset ishorasini unutish
- 8.5 Serverda mahalliy getterlar
- 9. Mashqlar
- 1-mashq (oson): Mahalliy ISO sana
- 2-mashq (o'rta): Toshkentda qaysi kun?
- 3-mashq (qiyin): Bron qachon?
- 4-mashq: Vazifalar qadami — muddat
- 10. Real ishda
- Xulosa
- Manbalar
JavaScript Date va vaqt zonalari: UTC, ISO 8601 va mahalliy vaqt
Qisqacha:
Dateichidagi timestamp zonasiz, lekin uning getterlari (getHours) kompyuter zonasida,getUTCHoursesa UTC'da ishlaydi. Sanani saqlash va yuborishda — UTC'dagi ISO 8601 matn (toISOString()→2026-10-05T12:00:00.000Z). Eng katta tuzoq:new Date("2026-10-05")UTC yarim tuni deb o'qiladi,new Date("2026-10-05T10:00")esa mahalliy vaqt deb. Kunlar farqiniDate.UTCbilan hisoblang — yozgi vaqt o'tadigan kun 23 soat bo'ladi.
Bu darsda
- UTC, mahalliy vaqt, offset va vaqt zonasi nomi (
Asia/Tashkent) farqini tushuntira olasiz. - ISO 8601 matnni o'qiysiz va yozasiz,
toISOStringbilan sanani serverga tayyorlaysiz. - Qaysi matn UTC, qaysi biri mahalliy vaqt deb o'qilishini bilasiz va "bir kunga siljish" xatosini tuzatasiz.
- Yozgi vaqt (DST) nima ekanini va nega "1 kun ≠ 24 soat" bo'lishi mumkinligini tushuntira olasiz.
- Ikki sana orasidagi kunlarni to'g'ri hisoblaysiz va sanalarni taqqoslaysiz.
Oldin bilishingiz kerak: Date asoslari, Son, sana, vaqt va rang maydonlari, JSON chuqur: replacer, reviver va chegaralar.
1. Nega bu kerak?
O'tgan darsda Sardor ochiqmi(sana) funksiyasini yozdi: soat 7 dan 23 gacha — ochiq. Toshkentda hammasi to'g'ri ishladi. Keyin uchta shikoyat keldi.
Birinchisi — Moskvada yashovchi mehmondan. U Toshkentga uchishdan oldin saytni ochgan. Moskva vaqti bilan 22:30 edi, Toshkentda esa 00:30 — «Bahor» allaqachon yopiq. Sayt esa "Hozir ochiq" deb yozgan.
Ikkinchisi — serverdan. Sardor buyurtma vaqtini log faylda ko'rdi: 12:00. Holbuki buyurtma soat 17:00 da kelgan edi. Server — ijaraga olingan kompyuter, boshqa davlatda turibdi va UTC soati bilan ishlaydi.
Uchinchisi — eng g'alatisi. Nyu-Yorkdagi qarindoshi orqali bron qilgan mehmon formada 5-oktabrni tanlagan. Tasdiqlash sahifasida esa "4-oktabr" chiqqan.
Uchala xatoning ildizi bitta: vaqt zonalari. Sana hisobidagi xatolarning aksariyati UTC va mahalliy vaqtni aralashtirishdan keladi. Bu darsda shu chalkashlikni bir marta va butunlay yechamiz. Son, sana, vaqt va rang maydonlari darsida "JavaScript'da qaytamiz" degan savol ham shu yerda yopiladi.
2. UTC, offset va vaqt zonasi
2.1 Bitta lahza — ko'p soat
Hozir dunyoning hamma joyida bitta lahza. Lekin devordagi soatlar har xil ko'rsatadi: Toshkentda 17:00, Moskvada 15:00, Londonda 13:00. Lahza bitta — "ko'rinishi" har xil.
Hisob boshi sifatida bitta "asosiy soat" kelishilgan — UTC (Coordinated Universal Time, "muvofiqlashtirilgan umumjahon vaqti"). Qolgan soatlar undan qancha oldinda yoki orqadaligi bilan aytiladi:
- Toshkent — UTC+5: UTC 12:00 bo'lsa, Toshkentda 17:00;
- Moskva — UTC+3: o'sha lahzada 15:00;
- Nyu-York yozda — UTC−4: o'sha lahzada 08:00.
+5, +3, −4 — offset ("siljish"), UTC dan farq. ISO matnda u +05:00 deb yoziladi.
O'tgan darsdan eslang: Date ichida timestamp saqlanadi, u lahzani bildiradi va zonaga bog'liq emas. Zona faqat bu lahzani soat-daqiqaga aylantirganda kerak bo'ladi. Darsda tez-tez mahalliy vaqt deymiz — bu kod ishlayotgan kompyuter zonasidagi devor soati. Toshkentdagi noutbukda u UTC+5, Moskvadagi serverda esa UTC+3 bo'ladi.
2.2 Vaqt zonasi — offset'dan ko'proq
Vaqt zonasi (time zone) — offset'ning o'zi emas, balki bir hududning soat qoidalari: hozir offset qancha, yozda o'zgaradimi, o'tmishda qanday bo'lgan. Zonalarning xalqaro ro'yxati bor — IANA vaqt zonalari bazasi (tz database). Unda har zona Qit'a/Shahar shaklida nomlanadi:
| Zona nomi | Hozirgi offset | Yozgi vaqt |
|---|---|---|
Asia/Tashkent |
+05:00 | yo'q |
Asia/Samarkand |
+05:00 | yo'q |
Europe/Moscow |
+03:00 | yo'q |
America/New_York |
−05:00 / −04:00 | bor |
Nega ikkita o'zbek zonasi? Ular tarixda farq qilgan, shuning uchun bazada alohida yuritiladi. Bugun ikkalasi ham UTC+5.
Offset vaqt o'tishi bilan o'zgarishi mumkin. O'zbekistonda ham shunday bo'lgan — Node'dan so'rab ko'ramiz:
const sana1985 = new Date("1985-07-01T12:00:00Z");
const sana2026 = new Date("2026-07-01T12:00:00Z");
console.log(String(sana1985));
console.log(String(sana2026));Konsolda:
Mon Jul 01 1985 19:00:00 GMT+0700 (Uzbekistan Summer Time)
Wed Jul 01 2026 17:00:00 GMT+0500 (Uzbekistan Standard Time)1985-yil yozida Toshkent UTC+7 da yashagan — yozgi vaqt bilan (u haqda «Yozgi vaqt» bo'limida). IANA bazasiga ko'ra, 1991-yildan keyin O'zbekistonda yozgi vaqt yo'q. Date buni o'zi biladi, chunki brauzer va Node ichida o'sha IANA bazasi bor. Shuning uchun dasturda offset'ni (+5) emas, zona nomini (Asia/Tashkent) saqlash to'g'riroq.
2.3 Kompyuteringiz qaysi zonada?
Kod qaysi zonada ishlayotganini so'rash mumkin:
const zona = Intl.DateTimeFormat().resolvedOptions().timeZone;
console.log(zona); // Asia/TashkentIntl — JavaScript'ning til va hudud vositalari to'plami. Uni Intl.DateTimeFormat darsida to'liq o'rganamiz. Hozir shu bitta qator yetarli: u kompyuter sozlamasidagi zona nomini qaytaradi. Sizda boshqacha chiqishi mumkin — kompyuteringiz qaysi zonada bo'lsa, shu.
Bu — Son, sana, vaqt va rang maydonlari darsidagi va'daning javobi. Bron formasi yuborilganda brauzer mehmonning zonasini ham qo'shib yuborishi mumkin: { vaqt: "2026-10-05T19:30", zona: "Europe/Moscow" }. Server endi "19:30" ning qaysi 19:30 ekanini aniq biladi.
2.4 getTimezoneOffset — teskari ishora
Eski usul — getTimezoneOffset(). U UTC va mahalliy vaqt farqini daqiqada beradi:
const sana = new Date("2026-10-05T12:00:00Z");
console.log(sana.getTimezoneOffset()); // -300Toshkent UTC+5, ya'ni +300 daqiqa. Metod esa -300 qaytardi — ishorasi teskari. U "mahalliy vaqtga nechchi daqiqa qo'shsam, UTC chiqadi" degan savolga javob beradi: 17:00 + (−300 daqiqa) = 12:00. Bu ham Date ning eski g'alati joylaridan. Yangi kodda zona nomi bilan ishlash qulayroq.
Tekshirib ko'ring: Moskvada (UTC+3)
getTimezoneOffset()nima qaytaradi?
Javob
-180. Moskva UTC dan 180 daqiqa oldinda, metod esa ishorani teskari beradi.
3. Mahalliy va UTC getterlar
3.1 Ikki to'plam
O'tgan darsdagi har getterning UTC "egizagi" bor: getUTCFullYear, getUTCMonth, getUTCDate, getUTCDay, getUTCHours, getUTCMinutes. Setterlar ham: setUTCHours va boshqalar.
const sana = new Date("2026-10-05T22:00:00Z");
console.log(sana.getHours(), sana.getUTCHours()); // 3 22
console.log(sana.getDate(), sana.getUTCDate()); // 6 5UTC bo'yicha hali 5-oktabr, soat 22:00. Toshkentda esa allaqachon 6-oktabr, tungi 03:00. Bitta lahza, ikki xil kun! Kechqurun va tunda bunday farq har kuni bo'ladi.
3.2 Date.UTC — UTC'da qismlardan yaratish
new Date(yil, oy, kun, ...) mahalliy vaqtni oladi. UTC'dagi lahzani qismlardan yasash uchun — Date.UTC. U Date emas, timestamp qaytaradi:
const ts = Date.UTC(2026, 9, 5, 12, 0);
console.log(ts); // 1791201600000
console.log(new Date(ts)); // 2026-10-05T12:00:00.000ZOy bu yerda ham 0 dan — 9 oktabr. Date.UTC ning natijasi kompyuter zonasiga bog'liq emas: Toshkentda ham, Nyu-Yorkda ham bir xil son chiqadi.
3.3 «Bahor» Toshkent soati bilan
Endi Moskvadagi mehmon muammosini yechamiz. Bizga mehmonning soati emas, Toshkent soati kerak. O'zbekistonda yozgi vaqt yo'q va offset doim +5. Demak, UTC soatiga 5 qo'shish yetarli:
function toshkentSoati(sana) {
return (sana.getUTCHours() + 5) % 24;
}
function ochiqmi(sana) {
const soat = toshkentSoati(sana);
return soat >= 7 && soat < 23;
}
const lahza = new Date("2026-10-05T19:30:00Z");
console.log(toshkentSoati(lahza)); // 0
console.log(ochiqmi(lahza)); // falseUTC 19:30 — Moskvada 22:30, Toshkentda 00:30. % 24 (bo'lishdagi qoldiq) 24 dan oshgan soatni sutka boshiga qaytaradi: 19 + 5 = 24 → 0. Endi javob mehmon qaysi zonada bo'lishidan qat'i nazar bir xil.
Diqqat: "UTC + 5" usuli faqat yozgi vaqtsiz zona uchun to'g'ri. Berlin yoki Nyu-York uchun offset yilda ikki marta o'zgaradi — u yerda qo'lda qo'shish xato beradi. Har qanday zona uchun ishlaydigan yo'l —
Intl.DateTimeFormatningtimeZonesozlamasi va Temporal. Ularni keyingi ikki darsda ko'ramiz.
4. ISO 8601 — sanani matnda yozish standarti
4.1 Tuzilishi
ISO 8601 — sana va vaqtni matnda yozishning xalqaro standarti. JavaScript, bazalar, API'lar, <input type="date"> — hammasi shu tilda gaplashadi:
2026-10-05T17:00:00.000+05:00| Bo'lak | Ma'nosi |
|---|---|
2026-10-05 |
yil-oy-kun (oy 1 dan!) |
T |
sana va vaqt ajratuvchisi |
17:00:00.000 |
soat:daqiqa:soniya.millisekund |
+05:00 yoki Z |
offset; Z — UTC (+00:00) |
Ikki afzalligi bor. Birinchisi — tartib "kattadan kichikka": yil, oy, kun, soat. Shuning uchun bir xil shakldagi ISO matnlarni oddiy matn sifatida saralasa ham, sana bo'yicha tartiblanadi. Ikkinchisi — offset bor: matn qaysi lahzani bildirishi aniq.
O'zingiz to'ldiring: ISO matn oxiridagi "bu UTC vaqti" degan harf — .
4.2 toISOString — doim UTC
const buyurtma = new Date(2026, 9, 5, 17, 0);
console.log(buyurtma.toISOString()); // 2026-10-05T12:00:00.000Z
console.log(JSON.stringify({ buyurtma }));Konsolda:
2026-10-05T12:00:00.000Z
{"buyurtma":"2026-10-05T12:00:00.000Z"}Toshkentda 17:00 da yaratilgan sana ISO'da 12:00:00.000Z bo'ldi. toISOString har doim UTC'ga aylantiradi va oxiriga Z qo'yadi. JSON chuqur darsida ko'rgan toJSON ham ichida aynan shuni chaqiradi.
Sardorning log'idagi 12:00 — xato emas edi. Bu UTC vaqti, Toshkentda esa 17:00. Ushlanmagan xatolar darsidagi xato hisobotida vaqt: new Date().toISOString() yozilishi ham shundan: server qayerda bo'lsa ham, vaqt bir ma'noli.
Qoida — sana bilan ishlashning oltin qoidasi:
- Saqlash va yuborish — UTC'da: timestamp yoki
toISOString(). - Ko'rsatish — foydalanuvchining zonasida (yoki biznes zonasida — «Bahor» uchun Toshkent).
Quyidagi diagramma buyurtma vaqtining yo'lini ko'rsatadi. Har bosqichda qaysi ko'rinishda ekaniga qarang:
sequenceDiagram
participant M as Mehmon brauzeri (Toshkent)
participant S as Server (UTC)
participant B as Baza
participant A as Admin brauzeri (Moskva)
M->>S: "2026-10-05T12:00:00.000Z"
S->>B: shu ISO matn yoki timestamp
B->>A: "2026-10-05T12:00:00.000Z"
Note over A: Toshkent vaqtida ko'rsatiladi: 17:00Yo'l bo'ylab vaqt faqat UTC'da yuradi. Soat-daqiqaga u faqat oxirida — ekranda aylanadi.
4.3 Offset'li matnni o'qish
ISO matnda offset bo'lsa, Date uni aniq lahzaga aylantiradi:
const a = new Date("2026-10-05T17:00:00+05:00");
const b = new Date("2026-10-05T15:00:00+03:00");
const c = new Date("2026-10-05T12:00:00Z");
console.log(a.getTime() === b.getTime()); // true
console.log(b.getTime() === c.getTime()); // trueUch xil yozuv — Toshkent, Moskva va UTC soati — bitta lahza.
Tekshirib ko'ring:
new Date("2026-10-05T23:30:00+05:00").toISOString()nima qaytaradi?
Javob
2026-10-05T18:30:00.000Z. Toshkent vaqtidan 5 soat ayiriladi — UTC'da hali o'sha kun, 18:30.
5. Matn qanday o'qiladi: eng katta tuzoq
5.1 Faqat sana — UTC, sana va vaqt — mahalliy
Bu qoidani yod oling, chunki u mantiqsiz tuyuladi:
const faqatSana = new Date("2026-10-05");
const sanaVaVaqt = new Date("2026-10-05T10:00");
console.log(faqatSana.toISOString()); // 2026-10-05T00:00:00.000Z
console.log(sanaVaVaqt.toISOString()); // 2026-10-05T05:00:00.000Z"2026-10-05"— offset'siz faqat sana → UTC yarim tuni deb o'qiladi;"2026-10-05T10:00"— offset'siz sana va vaqt → mahalliy vaqt deb o'qiladi (Toshkentda 10:00, ya'ni UTC 05:00).
Nega bunday? Bu — tarixiy murosa. Qisqasi:
- 2009-yil (ES5): offset'siz matn — UTC.
- 2015-yil (ES2015):
"2026-10-05T10:00"yozgan odam deyarli doim "mening soatim bilan 10:00" ni nazarda tutadi — demak, mahalliy vaqt. Qoida hamma offset'siz matn uchun shunday o'zgartirildi. - 2016-yil (ES2016): bu o'zgarish faqat sana yozilgan ko'p saytni buzdi. Shuning uchun faqat sana uchun UTC qaytarildi.
Natijada ikki qoida yonma-yon yashaydi. Tarixni yodlash shart emas — qoidaning o'zini va quyidagi sxemani eslab qoling.
Qaror qabul qilishni osonlashtirish uchun shu sxemadan foydalaning:
flowchart TD
A["new Date(matn)"] --> B{"Oxirida Z yoki +05:00 bormi?"}
B -->|ha| C["Aniq lahza ✅"]
B -->|yo'q| D{"Faqat sanami? 2026-10-05"}
D -->|ha| E["UTC yarim tuni ⚠️"]
D -->|"yo'q, vaqt ham bor"| F{"ISO shaklidami? T bilan"}
F -->|ha| G["Mahalliy vaqt"]
F -->|yo'q| H["Dvigatelga bog'liq ❌"]5.2 Nyu-Yorkdagi "4-oktabr"
Endi uchinchi shikoyatni tushunamiz. Forma 2026-10-05 yubordi, sahifa uni new Date("2026-10-05") bilan o'qib, getDate() bilan kunini chiqardi.
Toshkentda: UTC yarim tuni = mahalliy 05:00, kun hamon 5. Nyu-Yorkda (yozda UTC−4): UTC yarim tuni = mahalliy 4-oktabr, 20:00. Kompyuter zonasini o'zgartirib, haqiqatan sinab ko'rdik:
const sana = new Date("2026-10-05");
console.log(sana.getDate(), sana.getHours());
console.log(String(sana));Nyu-York zonasida ishga tushirilganda:
4 20
Sun Oct 04 2026 20:00:00 GMT-0400 (Eastern Daylight Time)Toshkentda xuddi shu kod 5 5 va Mon Oct 05 2026 05:00:00 GMT+0500 beradi. Bu kodni o'zingiz boshqa zonada sinash uchun Node'ga TZ muhit o'zgaruvchisini bering:
# macOS, Linux:
TZ=America/New_York node sana.mjs
# Windows PowerShell:
$env:TZ = "America/New_York"; node sana.mjsDiqqat: Windows'dagi Git Bash'da
TZ=... nodeishlamadi — Node zonani o'zgartirmadi. Git BashTZo'zgaruvchisini o'zicha qayta ishlaydi. Biz PowerShell'da sinadik.
Tuzatish. Faqat sana bo'lgan matnni new Date(...) ga bermang. Uni bo'laklarga ajrating va qismlardan yarating:
function sananiOqi(matn) {
const [yil, oy, kun] = matn.split("-").map(Number);
return new Date(yil, oy - 1, kun);
}
const bron = sananiOqi("2026-10-05");
console.log(bron.getDate(), bron.getHours()); // 5 0Endi bu — mahalliy yarim tun, istalgan zonada getDate() = 5. oy - 1 — oyni Date tiliga o'giramiz.
5.3 datetime-local qiymati
Son, sana, vaqt va rang maydonlari darsidagi <input type="datetime-local"> qiymati — 2026-10-05T19:30. Bu offset'siz sana-vaqt, demak new Date uni mahalliy deb o'qiydi. Mehmonning kompyuteri Toshkentda bo'lsa — to'g'ri. Moskvada bo'lsa — Moskva vaqtidagi 19:30. Shuning uchun xalqaro mehmonlari bor tizimda vaqt bilan birga zona nomi ham yuboriladi.
5.4 ISO bo'lmagan matnlar — dvigatelga bog'liq
O'tgan darsda "05.10.2026" ning 10-may bo'lib qolganini ko'rgandik. Yana ikki misol:
console.log(String(new Date("2026-10-05 10:00")));
console.log(String(new Date("2026-02-30")));Konsolda:
Mon Oct 05 2026 10:00:00 GMT+0500 (Uzbekistan Standard Time)
Mon Mar 02 2026 05:00:00 GMT+0500 (Uzbekistan Standard Time)Birinchisida T o'rnida bo'sh joy — bu ISO emas, lekin V8 (Chrome va Node) uni mahalliy vaqt deb tushundi. Ikkinchisida 30-fevral — bunday kun yo'q. Standart bo'yicha natija Invalid Date bo'lishi kerak. V8 esa uni jim 2-martga surib yubordi. Boshqa dvigatellar (masalan, Firefox) bunday matnga Invalid Date qaytarishi mumkin. Bitta kod — har brauzerda har xil natija.
Qoida: new Date(matn) ga faqat to'liq, offset'li ISO matn bering. Qolgan hamma narsani o'zingiz bo'laklarga ajratib o'qing.
Tekshirib ko'ring: Toshkentda
new Date("2026-10-05T00:00").getUTCDate()nechchi?
Javob
4. Bu offset'siz sana-vaqt, mahalliy yarim tun deb o'qiladi. Toshkent yarim tuni UTC'da 4-oktabr, 19:00. getUTCDate() UTC kunini beradi.
6. Yozgi vaqt (DST): kun har doim 24 soat emas
6.1 Nima u
Yozgi vaqt (daylight saving time, DST) — ko'p davlatlarda bahorda soatni bir soat oldinga suradilar, kuzda qaytaradilar. Maqsad — kechqurun quyosh yorug'idan ko'proq foydalanish. Yevropa Ittifoqi, AQSh, Kanada shunday qiladi. O'zbekiston, Rossiya, Xitoy — yo'q.
Shu kunlarda g'alati narsalar bo'ladi. 2026-yil 29-martda Berlinda soat 02:00 da to'g'ridan-to'g'ri 03:00 ga o'tiladi: 02:30 degan vaqt umuman bo'lmaydi. Demak, o'sha sutka 23 soat davom etadi. Kuzda esa bitta soat ikki marta o'tadi va sutka 25 soat bo'ladi.
Buni offset'li ISO matnlar bilan istalgan kompyuterda tekshirish mumkin. Berlinda 29-mart yarim tunida offset +01:00, 30-mart yarim tunida esa +02:00:
const yarimTun29 = new Date("2026-03-29T00:00:00+01:00");
const yarimTun30 = new Date("2026-03-30T00:00:00+02:00");
const soatlar = (yarimTun30 - yarimTun29) / (60 * 60 * 1000);
console.log(soatlar); // 236.2 "24 soat qo'shish" va "1 kun qo'shish" — har xil
Kompyuter Berlin zonasida bo'lsa, quyidagi kod ikki xil natija beradi. Biz uni TZ=Europe/Berlin bilan ishga tushirdik:
const ertalab = new Date(2026, 2, 28, 10, 0);
const plus24 = new Date(ertalab.getTime() + 24 * 60 * 60 * 1000);
const plusKun = new Date(ertalab);
plusKun.setDate(plusKun.getDate() + 1);
console.log(plus24.getHours(), plusKun.getHours());
console.log(String(new Date(2026, 2, 29, 2, 30)));Berlin zonasida:
11 10
Sun Mar 29 2026 03:30:00 GMT+0200 (Central European Summer Time)- 24 soat qo'shdik — ertasi kun 11:00 bo'ldi. Bir soat "yo'qolgan" edi.
setDate(+1)— kalendar bo'yicha ertasi kun, soat o'zgarmadi: 10:00.- Mavjud bo'lmagan 02:30 ni so'radik —
Dateuni 03:30 ga surdi.
Toshkentda ikkala usul ham 10 10 beradi, chunki bizda DST yo'q. Lekin «Bahor» sayti xalqaro mehmon uchun ham ishlaydi va serveringiz Yevropada bo'lishi mumkin.
Qoida: "ertaga shu soatda" kerak bo'lsa — kalendar bo'yicha (setDate). "Aniq 24 soatdan keyin" kerak bo'lsa (masalan, token muddati) — millisekund bilan. Bu ikki xil savol.
Tekshirib ko'ring: Kuzda, soat orqaga qaytariladigan kuni, Berlinda sutka necha soat?
Javob
25 soat. Soat 03:00 dan 02:00 ga qaytariladi va 02:00–03:00 oralig'i ikki marta o'tadi.
7. Farqni hisoblash va taqqoslash
7.1 Kunlar farqi — Date.UTC bilan
Mehmon 12-oktabrga stol bron qildi. Bugun 5-oktabr. Necha kun qoldi? Birinchi fikr — ayirib, sutkadagi millisekundlarga bo'lish. Lekin DST'li zonada bitta sutka 23 soat bo'lsa, natija 6.958... chiqadi.
Ishonchli usul: ikkala sanani UTC yarim tuniga keltirib, keyin ayirish. UTC'da DST yo'q — har sutka aniq 24 soat:
const KUN_MS = 24 * 60 * 60 * 1000;
function kunlarFarqi(boshi, oxiri) {
const a = Date.UTC(
boshi.getFullYear(), boshi.getMonth(), boshi.getDate(),
);
const b = Date.UTC(
oxiri.getFullYear(), oxiri.getMonth(), oxiri.getDate(),
);
return Math.round((b - a) / KUN_MS);
}
const bugun = new Date(2026, 9, 5, 21, 40);
const bronKuni = new Date(2026, 9, 12, 10, 0);
console.log(kunlarFarqi(bugun, bronKuni)); // 7Har sanadan faqat mahalliy yil, oy va kunni oldik — soatni tashladik. Keyin shu kunni UTC'da qayta qurdik. Math.round — xavfsizlik uchun: bo'lish natijasi har doim butun bo'lsin. Soatlarni ham ayirganimizda bugun dagi 21:40 natijani taxminan 6.5 ga tushirardi. "Necha kun qoldi" savolida esa odam kalendar varaqlarini sanaydi.
7.2 Bir kunmi?
"Bugungi buyurtmalar" ro'yxati uchun ikki sana bitta kunga tegishlimi, bilish kerak. Uchta qismni solishtiramiz:
function birKunmi(a, b) {
return a.getFullYear() === b.getFullYear()
&& a.getMonth() === b.getMonth()
&& a.getDate() === b.getDate();
}
const ertalab = new Date("2026-10-05T03:00:00Z");
const kechasi = new Date("2026-10-05T20:00:00Z");
console.log(birKunmi(ertalab, kechasi)); // falseUTC bo'yicha ikkalasi ham 5-oktabr. Toshkentda esa birinchisi 5-oktabr 08:00, ikkinchisi — 6-oktabr 01:00. "Bir kunmi?" degan savol doim "qaysi zonada bir kun?" degan savolni ham o'z ichiga oladi. Mahalliy getterlar — kompyuter zonasida.
7.3 Saralash va eng kech sana
Sanalar massivini saralash — ayirma bilan:
const buyurtmalar = [
new Date("2026-10-05T14:10:00Z"),
new Date("2026-10-05T09:45:00Z"),
new Date("2026-10-05T12:00:00Z"),
];
const tartiblangan = buyurtmalar.toSorted((a, b) => a - b);
console.log(tartiblangan.map((s) => s.toISOString().slice(11, 16)));
const engKechi = new Date(Math.max(...buyurtmalar));
console.log(engKechi.toISOString()); // 2026-10-05T14:10:00.000ZKonsolda:
[ '09:45', '12:00', '14:10' ]
2026-10-05T14:10:00.000Za - b sanalarni timestamp'ga aylantiradi. Math.max ham argumentlarni songa aylantiradi va son qaytaradi — shuning uchun natijani yana new Date(...) ga o'radik. slice(11, 16) ISO matndan HH:MM bo'lagini kesib oladi (UTC'da).
Tekshirib ko'ring:
"2026-10-05T09:45:00Z" < "2026-10-05T14:10:00Z"— matnlarni solishtirish to'g'ri javob beradimi?
Javob
Ha, true. Bir xil shakldagi ISO matnlar (ikkalasi ham Z bilan, bir xil uzunlikda) harfma-harf solishtirilganda ham sana tartibida bo'ladi. Lekin biri Z, ikkinchisi +05:00 bilan bo'lsa — matn solishtirish xato beradi. Ishonchli yo'l — Date ga aylantirib solishtirish.
8. Ko'p uchraydigan xatolar
8.1 "Bugungi sana" uchun toISOString().slice(0, 10)
Juda ko'p uchraydigan xato:
const ertalab = new Date(2026, 9, 5, 3, 0);
console.log(ertalab.toISOString().slice(0, 10)); // 2026-10-04Toshkentda 5-oktabr, tungi 03:00. toISOString esa UTC'ga o'tkazdi — u yerda hali 4-oktabr, 22:00. Natijada soat 00:00 dan 05:00 gacha bu kod har kuni kechagi sanani beradi. Buni faqat tunda ishlaydigan odam sezadi. Tuzatish: mahalliy getterlar bilan yig'ing (1-mashq).
8.2 new Date("YYYY-MM-DD") bilan sana o'qish
Kompyuter UTC dan orqadagi zonada (Amerika) bo'lsa, kun bittaga kamayadi. Tuzatish: matnni bo'laklarga ajratib, new Date(yil, oy - 1, kun) — «Nyu-Yorkdagi "4-oktabr"» bo'limidagi sananiOqi.
8.3 Offset'ni zona deb saqlash
"Foydalanuvchi zonasi: +2" deb saqlangan Berlin mehmoni oktabr oxirida bir soatga adashadi — qishda Berlin +1. Tuzatish: Europe/Berlin kabi IANA nomini saqlang.
8.4 getTimezoneOffset ishorasini unutish
Toshkentda -300, lekin zona UTC**+**5. Offset'ni qo'lda qo'shayotganda ishorasini almashtirish shart. Tuzatish: imkon bo'lsa, Intl yoki Temporal'dan foydalaning — ular zona nomi bilan ishlaydi.
8.5 Serverda mahalliy getterlar
Server odatda UTC zonasida ishlaydi. Unda getHours() UTC soatini beradi, Toshkent soatini emas. Kompyuteringizda to'g'ri ishlagan kod serverda 5 soatga "adashadi". Tuzatish: serverda biznes zonasini (Asia/Tashkent) kodda aniq ko'rsating.
9. Mashqlar
1-mashq (oson): Mahalliy ISO sana
mahalliySana(sana) sanani YYYY-MM-DD shaklida, mahalliy vaqt bo'yicha qaytarsin. Ishora: getFullYear, getMonth() + 1, getDate va padStart.
console.log(mahalliySana(new Date(2026, 9, 5, 3, 0))); // 2026-10-05
console.log(mahalliySana(new Date(2026, 0, 9))); // 2026-01-09Yechim
function mahalliySana(sana) {
const yil = sana.getFullYear();
const oy = String(sana.getMonth() + 1).padStart(2, "0");
const kun = String(sana.getDate()).padStart(2, "0");
return `${yil}-${oy}-${kun}`;
}
console.log(mahalliySana(new Date(2026, 9, 5, 3, 0))); // 2026-10-05
console.log(mahalliySana(new Date(2026, 0, 9))); // 2026-01-09toISOString().slice(0, 10) tungi 03:00 da 2026-10-04 qaytarardi. Mahalliy getterlar esa Toshkentdagi haqiqiy kunni beradi. padStart(2, "0") — 1 ni 01 qiladi: ISO'da oy va kun doim ikki xonali.
2-mashq (o'rta): Toshkentda qaysi kun?
toshkentSanasi(sana) — berilgan lahza Toshkentda qaysi sana ekanini YYYY-MM-DD qilib qaytarsin, kompyuter zonasidan qat'i nazar. Ishora: lahzaga 5 soat qo'shing (getTime() + 5 * 60 * 60 * 1000) va natijaning UTC qismlarini oling. Bu faqat DST'siz zona uchun to'g'ri.
const kechasi = new Date("2026-10-05T20:00:00Z");
const kechqurun = new Date("2026-10-05T18:59:00Z");
console.log(toshkentSanasi(kechasi)); // 2026-10-06
console.log(toshkentSanasi(kechqurun)); // 2026-10-05Yechim
const TOSHKENT_OFFSET_MS = 5 * 60 * 60 * 1000;
function toshkentSanasi(sana) {
const siljigan = new Date(sana.getTime() + TOSHKENT_OFFSET_MS);
return siljigan.toISOString().slice(0, 10);
}
const kechasi = new Date("2026-10-05T20:00:00Z");
const kechqurun = new Date("2026-10-05T18:59:00Z");
console.log(toshkentSanasi(kechasi)); // 2026-10-06
console.log(toshkentSanasi(kechqurun)); // 2026-10-05Lahzani 5 soatga surdik. Endi uning UTC ko'rinishi Toshkent devor soati bilan bir xil. toISOString UTC'da ishlagani uchun bu yerda aynan kerakli narsa — «Ko'p uchraydigan xatolar» bo'limidagi toISOString().slice(0, 10) xatosining teskarisi. UTC 20:00 — Toshkentda ertasi kun 01:00. Bu "hiyla" faqat ko'rsatish uchun: surilgan sanani saqlamang, u boshqa lahza.
3-mashq (qiyin): Bron qachon?
bronMatni(bugun, bronSanaMatni) — bron sanasi "YYYY-MM-DD" matn ko'rinishida keladi. Funksiya "bugun", "ertaga", "N kundan keyin" yoki "o'tib ketgan" qaytarsin. Ishora: matnni «Nyu-Yorkdagi "4-oktabr"» bo'limidagi sananiOqi usulida o'qing, keyin kunlarFarqi.
const bugun = new Date(2026, 9, 5, 21, 40);
console.log(bronMatni(bugun, "2026-10-05")); // bugun
console.log(bronMatni(bugun, "2026-10-06")); // ertaga
console.log(bronMatni(bugun, "2026-10-12")); // 7 kundan keyin
console.log(bronMatni(bugun, "2026-10-01")); // o'tib ketganYechim
const KUN_MS = 24 * 60 * 60 * 1000;
function sananiOqi(matn) {
const [yil, oy, kun] = matn.split("-").map(Number);
return new Date(yil, oy - 1, kun);
}
function kunlarFarqi(boshi, oxiri) {
const a = Date.UTC(
boshi.getFullYear(), boshi.getMonth(), boshi.getDate(),
);
const b = Date.UTC(
oxiri.getFullYear(), oxiri.getMonth(), oxiri.getDate(),
);
return Math.round((b - a) / KUN_MS);
}
function bronMatni(bugun, bronSanaMatni) {
const farq = kunlarFarqi(bugun, sananiOqi(bronSanaMatni));
if (farq < 0) return "o'tib ketgan";
if (farq === 0) return "bugun";
if (farq === 1) return "ertaga";
return `${farq} kundan keyin`;
}
const bugun = new Date(2026, 9, 5, 21, 40);
console.log(bronMatni(bugun, "2026-10-05")); // bugun
console.log(bronMatni(bugun, "2026-10-06")); // ertaga
console.log(bronMatni(bugun, "2026-10-12")); // 7 kundan keyin
console.log(bronMatni(bugun, "2026-10-01")); // o'tib ketganbugun 21:40 da bo'lsa ham, "ertaga" to'g'ri chiqdi — soatlar hisobga olinmadi. Bron matnini new Date("2026-10-06") bilan o'qisak, Amerikada "bugun" chiqishi mumkin edi. "3 kundan keyin" kabi matnlarni har tilda to'g'ri chiqaradigan tayyor vosita bor — Intl.RelativeTimeFormat.
4-mashq: Vazifalar qadami — muddat
vazifalar hali sana saqlamaydi, shuning uchun bu safar ham alohida faylda ishlaymiz. kurs/mashqlar/12/12-zona/muddat.mjs faylini yarating. Vazifalarda muddat maydoni bor — "YYYY-MM-DD" matn (forma <input type="date"> dan keladi). Berilgan "bugun" uchun muddati o'tganlarini va bugungi vazifalarni chiqaring. Ishora: 3-mashqdagi sananiOqi va kunlarFarqi.
const bugun = new Date(2026, 9, 5, 9, 0);
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
const KUN_MS = 24 * 60 * 60 * 1000;
function sananiOqi(matn) {
const [yil, oy, kun] = matn.split("-").map(Number);
return new Date(yil, oy - 1, kun);
}
function kunlarFarqi(boshi, oxiri) {
const a = Date.UTC(
boshi.getFullYear(), boshi.getMonth(), boshi.getDate(),
);
const b = Date.UTC(
oxiri.getFullYear(), oxiri.getMonth(), oxiri.getDate(),
);
return Math.round((b - a) / KUN_MS);
}
const bugun = new Date(2026, 9, 5, 9, 0);
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 = kunlarFarqi(bugun, sananiOqi(vazifa.muddat));
if (qoldi < 0) {
console.log(`MUDDATI O'TGAN (${-qoldi} kun): ${vazifa.matn}`);
} else if (qoldi === 0) {
console.log(`BUGUN: ${vazifa.matn}`);
}
}Konsolda:
BUGUN: Non olish
MUDDATI O'TGAN (2 kun): Kommunal to'lovMuddat — "devor kalendaridagi kun", lahza emas. Shuning uchun uni mahalliy yarim tun sifatida o'qidik va soatsiz solishtirdik. Terminalda: node 12/12-zona/muddat.mjs.
git add 12/12-zona/muddat.mjs
git commit -m "12/12: vazifa muddatini mahalliy sana bilan hisobla"10. Real ishda
- Backend va bazalar. Qoida hamma joyda bir xil: bazada UTC (PostgreSQL'da
timestamptzturi), API'da ISO 8601Zbilan, ekranda — foydalanuvchi zonasida. Serverlar va Docker konteynerlar odatda UTC'da ishlaydi. - Foydalanuvchi zonasi. Bron, uchrashuv, yetkazib berish vaqti — brauzerdan
Intl.DateTimeFormat().resolvedOptions().timeZoneolinib, profilda saqlanadi. - Xalqaro xizmatlar. Taksi, aviachipta, onlayn kurs jadvali — hammasida DST bor zonalar uchrashadi. "Uchrashuv 25 soat davom etdi" kabi xatolar shu yerdan.
- Intervyu. "
new Date('2026-10-05')nega Amerikada boshqa kun beradi?", "Sanani bazada qanday saqlaysiz?", "DST nima?" — middle darajadagi intervyularda ko'p so'raladi.
Xulosa
- Timestamp — lahza, zonasiz.
get...getterlar — kompyuter zonasida,getUTC...— UTC'da.Date.UTC(...)— UTC qismlardan timestamp. - Vaqt zonasi — offset emas, qoidalar to'plami; uni IANA nomi bilan saqlang (
Asia/Tashkent). O'zbekistonda 1991-yildan beri DST yo'q, offset +05:00. toISOString()— doim UTC vaZ; saqlash va yuborish — UTC'da, ko'rsatish — kerakli zonada."2026-10-05"— UTC yarim tuni,"2026-10-05T10:00"— mahalliy vaqt; ISO bo'lmagan matnlar — dvigatelga bog'liq. Faqat sanani o'zingiz bo'laklab o'qing.- DST'li zonada sutka 23 yoki 25 soat: "24 soat qo'shish" ≠ "1 kun qo'shish". Kunlar farqi —
Date.UTCbilan, soatsiz. - Solishtirish — timestamp bilan; "bir kunmi?" — doim "qaysi zonada?" savoli bilan.
Keyingi dars: Temporal API va sana kutubxonalari — Date ning bu muammolarini tub-tubidan hal qiladigan yangi standart (PlainDate, ZonedDateTime, Duration) va date-fns, Day.js, Luxon kutubxonalari.
Manbalar
- MDN: "Date" (Date time string format, Time zone offset), "Date.prototype.toISOString", "Date.UTC", "Date.prototype.getTimezoneOffset" — developer.mozilla.org
- ECMAScript 2025 Language Specification, 21.4.1 "Time Values and Time Range", 21.4.3.2 "Date.parse" — tc39.es/ecma262
- IANA Time Zone Database — iana.org/time-zones
Izohlar (0)
Izoh yozish uchun kiring.
- Hozircha izoh yo'q. Birinchi bo'ling!