Mundarija (21)
- 1. Kirish va motivatsiya
- 2. Nazariya — chuqur tushuntirish
- 2.1. Siljish va mintaqa
- 2.2. zoneinfo va tzdata
- 2.3. astimezone va replace(tzinfo=...)
- 2.4. Yozgi vaqt: bo'shliq va takror
- 2.5. Arifmetika: devor soati yoki haqiqiy vaqt
- 2.6. Tarix va siyosat
- 2.7. Qoidalar
- 3. Tez ma'lumotnoma
- 4. Batafsil misollar
- Misol 1 — Mintaqalar asoslari
- Misol 2 — Yozgi vaqt: bo'shliq va takror
- Misol 3 — Arifmetika: devor soati va haqiqiy vaqt
- Misol 4 — Amaliy: xalqaro jamoa uchun kundalik uchrashuvlar
- 5. To'g'ri va noto'g'ri tushunishlar
- 6. Keng tarqalgan xatolar va yechimlari
- 7. Integratsiya — bu bilim qayerda kerak bo'ladi
- 8. Eng yaxshi amaliyotlar
- 9. Amaliy topshiriq
- Xulosa
15.5-dars: Vaqt mintaqalari va zoneinfo
15-QISM — STANDART KUTUBXONA · 5-dars
1. Kirish va motivatsiya
15.4-darsda sanalar bilan ishlashni o'rgandik, lekin bitta savolni chetga surdik: "14:00" — qaysi joydagi 14:00?
Toshkentdagi 14:00, Berlindagi 14:00 va Nyu-Yorkdagi 14:00 — uchta turli vaqt nuqtasi. Bundan tashqari, ko'p mamlakatlarda yiliga ikki marta soatlar suriladi (yozgi vaqt, DST): bahorda bir soat yo'qoladi, kuzda bir soat ikki marta takrorlanadi.
Real vaziyat. O'zbekistondagi kompaniya Germaniyadagi hamkorlar bilan har kuni 09:00 (Berlin vaqti) da uchrashuv o'tkazadi. Taqvim tizimi uchrashuvni bir marta yaratib, keyingi kunlarni + timedelta(hours=24) bilan hisoblardi — UTC da. 29-martdan keyin Berlinda soatlar oldinga surildi va uchrashuv nemis hamkorlar uchun 10:00 ga ko'chdi. Toshkent tomonda esa hech kim buni sezmadi: O'zbekistonda 1992-yildan beri yozgi vaqt yo'q.
Boshqa jamoa foydalanuvchi vaqtini "2026-03-01T09:00+01:00" shaklida saqlagan. Olti oydan keyingi eslatma ham +01:00 bilan hisoblandi — lekin sentabrda Berlin +02:00 da. Eslatma bir soat kechikdi: +01:00 — bu mintaqa emas, faqat o'sha lahzadagi siljish.
Bu darsda zoneinfo bilan to'g'ri ishlashni, yozgi vaqt tuzoqlarini va "UTC da saqlash, mahalliy vaqtda ko'rsatish" qoidasini amalda o'rganamiz.
Bu darsda:
- Mintaqa (
Asia/Tashkent) va siljish (+05:00) — farqi zoneinfo.ZoneInfova Windows'datzdata- UTC da saqlash,
astimezonebilan ko'rsatish - Mavjud bo'lmagan va ikki marta takrorlanadigan vaqtlar,
fold - Bir mintaqa ichidagi arifmetika — devor soati bo'yicha
- Tarixiy o'zgarishlar: Toshkent siljishlari
- Amaliy: turli mamlakatlar uchun kundalik eslatmalar jadvali
2. Nazariya — chuqur tushuntirish
2.1. Siljish va mintaqa
| Tushuncha | Misol | Nimani biladi |
|---|---|---|
| UTC | UTC |
Hamma narsaning asosi, yozgi vaqt yo'q |
| Siljish (offset) | +05:00, timezone(timedelta(hours=5)) |
Faqat bitta raqam |
| Mintaqa (IANA) | Asia/Tashkent, Europe/Berlin |
Siljish qoidalari tarixi: yozgi vaqt, qonun o'zgarishlari |
+01:00 dan mintaqani tiklab bo'lmaydi: Berlin, Parij, Lagos — hammasi qishda +01:00, lekin yozda Berlin va Parij +02:00, Lagos esa +01:00 da qoladi.
| Tur | Qachon |
|---|---|
datetime.UTC / timezone.utc |
Saqlash va hisoblash |
timezone(timedelta(...)) |
Qat'iy siljish — ISO satrdan o'qilganda shunday bo'ladi |
ZoneInfo("Europe/Berlin") |
Foydalanuvchiga ko'rsatish, kalendar voqealari |
2.2. zoneinfo va tzdata
from zoneinfo import ZoneInfo, available_timezones
TOSHKENT = ZoneInfo("Asia/Tashkent")
datetime(2026, 9, 17, 14, 0, tzinfo=TOSHKENT) # 2026-09-17 14:00:00+05:00| Platforma | IANA ma'lumotlar bazasi |
|---|---|
| Linux, macOS | Tizimda bor (/usr/share/zoneinfo) |
| Windows | Yo'q — pip install tzdata |
Docker slim obrazlar |
Ko'pincha yo'q — tzdata paketi |
tzdata siz: ZoneInfoNotFoundError: 'No time zone found with key Asia/Tashkent'. Ilovangiz bog'liqliklariga tzdata ni qo'shing — shunda hamma platformada bir xil ishlaydi.
ZoneInfo obyektlari keshlanadi: ZoneInfo("Asia/Tashkent") is ZoneInfo("Asia/Tashkent") → True.
2.3. astimezone va replace(tzinfo=...)
| Metod | Nima qiladi | Vaqt nuqtasi |
|---|---|---|
aware.astimezone(zona) |
Boshqa mintaqaga o'giradi | O'zgarmaydi |
naive.replace(tzinfo=zona) |
Mintaqani yopishtiradi | "Bu devor soati shu zonada" |
aware.replace(tzinfo=boshqa) |
Yopishtiradi | Boshqa nuqtaga aylanadi |
naive.astimezone(zona) |
Naive ni server mahalliy vaqti deb oladi | Serverga bog'liq |
utc_vaqt = datetime(2026, 9, 17, 9, 0, tzinfo=UTC)
utc_vaqt.astimezone(ZoneInfo("Asia/Tashkent")) # 14:00+05:00 — o'sha lahza
utc_vaqt.astimezone(ZoneInfo("America/New_York")) # 05:00-04:00 — o'sha lahzaSolishtirish:
| Holat | Qanday solishtiriladi |
|---|---|
Aware, turli tzinfo |
UTC ga o'girib — to'g'ri |
Aware, bir xil tzinfo |
Devor soati bo'yicha — fold e'tiborsiz |
| Naive va aware | == → False, < → TypeError |
2.4. Yozgi vaqt: bo'shliq va takror
Bahor — bo'shliq (gap). Berlin, 2026-yil 29-mart: 02:00 dan to'g'ridan-to'g'ri 03:00 ga. 02:30 mavjud emas.
Kuz — takror (fold). 25-oktabr: 03:00 dan yana 02:00 ga. 02:30 ikki marta bo'ladi.
datetime bu holatlarni fold atributi (0 yoki 1) bilan ifodalaydi (PEP 495):
| Holat | fold=0 |
fold=1 |
|---|---|---|
| Takror (kuz) | Birinchi 02:30 (+02:00) |
Ikkinchi 02:30 (+01:00) |
| Bo'shliq (bahor) | Siljish o'tishdan oldingi | O'tishdan keyingi |
Mavjud bo'lmagan vaqt xato bermaydi — u yaratiladi, UTC ga o'girib qaytarilganda esa boshqa devor soatiga aylanadi (02:30 → 03:30).
Aniqlash usuli — UTC orqali aylanib kelish:
def mavjudmi(d: datetime) -> bool:
qaytgan = d.astimezone(UTC).astimezone(d.tzinfo)
return qaytgan.replace(tzinfo=None) == d.replace(tzinfo=None)
def ikki_manolimi(d: datetime) -> bool:
return d.replace(fold=0).utcoffset() != d.replace(fold=1).utcoffset()2.5. Arifmetika: devor soati yoki haqiqiy vaqt
Bir xil tzinfo li aware datetime larda arifmetika devor soati bo'yicha bajariladi:
b = ZoneInfo("Europe/Berlin")
s = datetime(2026, 3, 28, 12, 0, tzinfo=b)
s + timedelta(days=1) # 29-mart 12:00+02:00 — devor soati bir xil
# haqiqatan o'tgan vaqt: 23 soat
(s.astimezone(UTC) + timedelta(hours=24)).astimezone(b) # 29-mart 13:00+02:00| Vazifa | To'g'ri usul |
|---|---|
| "Ertaga shu vaqtda" (uchrashuv, eslatma) | Mahalliy devor soatida qo'shish |
| "24 soatdan keyin" (muddat, token, SLA) | UTC da qo'shish |
| Ikki lahza orasidagi haqiqiy vaqt | Ikkalasini UTC ga o'girib ayirish |
Bir mintaqadagi ikki datetime ni ayirish ham devor soati farqini beradi: 29-mart 12:00 − 28-mart 12:00 → 1 day, haqiqatda esa 23 soat.
2.6. Tarix va siyosat
Mintaqa qoidalari qonun bilan o'zgaradi — shuning uchun tzdata muntazam yangilanadi.
| Yil | Asia/Tashkent yozda |
|---|---|
| 1990 | +07:00 |
| 1991 | +06:00 |
| 1992 dan beri | +05:00, yozgi vaqt yo'q |
Kelajakdagi voqealar uchun (bir yildan keyingi uchrashuv) mahalliy vaqt + mintaqa nomi saqlanadi: agar qoidalar o'zgarsa, UTC qayta hisoblanadi. O'tgan voqealar uchun — UTC.
2.7. Qoidalar
| Qatlam | Nima |
|---|---|
| Baza / jurnal / API | Aware UTC (timestamptz, ISO 8601 Z yoki +00:00) |
| Foydalanuvchi profili | IANA mintaqa nomi (Asia/Tashkent), siljish emas |
| Ko'rsatish | astimezone(ZoneInfo(foydalanuvchi.mintaqa)) |
| Kelajakdagi kalendar voqeasi | Mahalliy vaqt + mintaqa nomi |
| Muddatlar, taymerlar | UTC + timedelta |
3. Tez ma'lumotnoma
from datetime import UTC, datetime, timedelta
from zoneinfo import ZoneInfo
TOSHKENT = ZoneInfo("Asia/Tashkent")
hozir = datetime.now(UTC) # saqlash
hozir.astimezone(TOSHKENT) # ko'rsatish
mahalliy = datetime(2026, 9, 17, 9, 0, tzinfo=ZoneInfo("Europe/Berlin"))
mahalliy.astimezone(UTC) # saqlashga
muddat = hozir + timedelta(hours=24) # haqiqiy 24 soat — UTC da
haqiqiy_farq = a.astimezone(UTC) - b.astimezone(UTC)
d.replace(fold=1) # takrorlanuvchi soatning ikkinchisiQoidalar
saqlash — UTC, ko'rsatish — ZoneInfo
profilda mintaqa nomi, siljish emas
Windows va slim konteynerlar — tzdata paketi
bir zona ichidagi arifmetika — devor soati
haqiqiy davomiylik — UTC ga o'girib
naive.astimezone() — server mintaqasiga bog'liq4. Batafsil misollar
Misol 1 — Mintaqalar asoslari
"""ZoneInfo yaratish; astimezone va replace farqi; turli zonalarni solishtirish; siljish va mintaqa; tarixiy siljishlar; noma'lum kalit."""
from datetime import UTC, datetime, timedelta, timezone
from zoneinfo import ZoneInfo, ZoneInfoNotFoundError, available_timezones
TOSHKENT = ZoneInfo("Asia/Tashkent")
BERLIN = ZoneInfo("Europe/Berlin")
NYU_YORK = ZoneInfo("America/New_York")
def main() -> None:
print("=== 1. Bitta lahza — turli mintaqalarda ===")
lahza = datetime(2026, 9, 17, 9, 0, tzinfo=UTC)
for zona in (UTC, TOSHKENT, BERLIN, NYU_YORK):
mahalliy = lahza.astimezone(zona)
print(f" {str(zona):17} {mahalliy:%Y-%m-%d %H:%M} siljish={mahalliy:%z} nomi={mahalliy.tzname()}")
print(f" hammasi teng: {len({lahza.astimezone(z) for z in (TOSHKENT, BERLIN, NYU_YORK)}) == 1}")
print("\n=== 2. ⚠️ astimezone va replace ===")
toshkent_14 = datetime(2026, 9, 17, 14, 0, tzinfo=TOSHKENT)
print(f" asl: {toshkent_14}")
print(f" astimezone(BERLIN): {toshkent_14.astimezone(BERLIN)} ← o'sha lahza")
print(f" replace(tzinfo=BERLIN): {toshkent_14.replace(tzinfo=BERLIN)} ← boshqa lahza")
farq = toshkent_14.replace(tzinfo=BERLIN) - toshkent_14
print(f" replace dan keyingi farq: {farq}")
print("\n=== 3. Siljish va mintaqa ===")
iso = datetime.fromisoformat("2026-03-01T09:00:00+01:00")
print(f" ISO satrdan tzinfo: {iso.tzinfo!r} (turi: {type(iso.tzinfo).__name__})")
olti_oy_siljish = iso + timedelta(days=184)
olti_oy_zona = iso.replace(tzinfo=BERLIN) + timedelta(days=184)
print(f" +184 kun, qat'iy siljish bilan: {olti_oy_siljish}")
print(f" +184 kun, Europe/Berlin bilan: {olti_oy_zona}")
print(f" UTC da farq: {olti_oy_siljish.astimezone(UTC) - olti_oy_zona.astimezone(UTC)} ← eslatma bir soat kechikadi")
for zona_nomi in ("Europe/Berlin", "Europe/Paris", "Africa/Lagos"):
z = ZoneInfo(zona_nomi)
qish, yoz = datetime(2026, 1, 15, 12, tzinfo=z), datetime(2026, 7, 15, 12, tzinfo=z)
print(f" {zona_nomi:14} qishda {qish:%z}, yozda {yoz:%z}")
print("\n=== 4. Tarix: Asia/Tashkent yozgi siljishi ===")
for yil in (1985, 1990, 1991, 1992, 2026):
print(f" {yil}-yil iyul: {datetime(yil, 7, 1, 12, tzinfo=TOSHKENT):%z}")
print("\n=== 5. Mavjud mintaqalar va xatolar ===")
zonalar = available_timezones()
print(f" jami 400 dan ko'p: {len(zonalar) > 400}")
print(f" O'zbekiston: {sorted(z for z in zonalar if z in ('Asia/Tashkent', 'Asia/Samarkand'))}")
try:
ZoneInfo("Toshkent")
except ZoneInfoNotFoundError as xato:
print(f" ZoneInfo('Toshkent') → {type(xato).__name__}: {xato}")
print(f" kesh: ZoneInfo(...) is ZoneInfo(...) → {ZoneInfo('Asia/Tashkent') is TOSHKENT}")
print(f" qat'iy siljish +05:00 mintaqa nomini bilmaydi: {timezone(timedelta(hours=5))}")
if __name__ == "__main__":
main()Natijaning muhim qismi:
=== 1. Bitta lahza — turli mintaqalarda ===
UTC 2026-09-17 09:00 siljish=+0000 nomi=UTC
Asia/Tashkent 2026-09-17 14:00 siljish=+0500 nomi=+05
Europe/Berlin 2026-09-17 11:00 siljish=+0200 nomi=CEST
America/New_York 2026-09-17 05:00 siljish=-0400 nomi=EDT
hammasi teng: True
=== 2. ⚠️ astimezone va replace ===
asl: 2026-09-17 14:00:00+05:00
astimezone(BERLIN): 2026-09-17 11:00:00+02:00 ← o'sha lahza
replace(tzinfo=BERLIN): 2026-09-17 14:00:00+02:00 ← boshqa lahza
replace dan keyingi farq: 3:00:00
=== 3. Siljish va mintaqa ===
ISO satrdan tzinfo: datetime.timezone(datetime.timedelta(seconds=3600)) (turi: timezone)
+184 kun, qat'iy siljish bilan: 2026-09-01 09:00:00+01:00
+184 kun, Europe/Berlin bilan: 2026-09-01 09:00:00+02:00
UTC da farq: 1:00:00 ← eslatma bir soat kechikadi
Europe/Berlin qishda +0100, yozda +0200
Europe/Paris qishda +0100, yozda +0200
Africa/Lagos qishda +0100, yozda +0100
=== 4. Tarix: Asia/Tashkent yozgi siljishi ===
1985-yil iyul: +0700
1990-yil iyul: +0700
1991-yil iyul: +0600
1992-yil iyul: +0500
2026-yil iyul: +0500
=== 5. Mavjud mintaqalar va xatolar ===
jami 400 dan ko'p: True
O'zbekiston: ['Asia/Samarkand', 'Asia/Tashkent']
ZoneInfo('Toshkent') → ZoneInfoNotFoundError: 'No time zone found with key Toshkent'
kesh: ZoneInfo(...) is ZoneInfo(...) → True
qat'iy siljish +05:00 mintaqa nomini bilmaydi: UTC+05:00Nima ko'rsatdi: 2.1, 2.2, 2.3, 2.6-bo'limlar.
Misol 2 — Yozgi vaqt: bo'shliq va takror
"""Bahorgi bo'shliq: mavjud bo'lmagan vaqt; kuzgi takror va fold; aniqlash funksiyalari; butun kunni soatma-soat ko'rish."""
from datetime import UTC, datetime, timedelta
from zoneinfo import ZoneInfo
BERLIN = ZoneInfo("Europe/Berlin")
TOSHKENT = ZoneInfo("Asia/Tashkent")
def mavjudmi(d: datetime) -> bool:
qaytgan = d.astimezone(UTC).astimezone(d.tzinfo)
return qaytgan.replace(tzinfo=None) == d.replace(tzinfo=None)
def ikki_manolimi(d: datetime) -> bool:
return d.replace(fold=0).utcoffset() != d.replace(fold=1).utcoffset()
def main() -> None:
print("=== 1. ⚠️ Bahor: 29-mart, Berlin ===")
for soat, daqiqa in ((1, 30), (2, 0), (2, 30), (3, 0), (3, 30)):
d = datetime(2026, 3, 29, soat, daqiqa, tzinfo=BERLIN)
print(f" {d:%H:%M} siljish={d:%z} mavjud={mavjudmi(d)!s:5} UTC={d.astimezone(UTC):%H:%M}")
yoq = datetime(2026, 3, 29, 2, 30, tzinfo=BERLIN)
print(f" 02:30 xato bermadi, UTC orqali qaytganda: {yoq.astimezone(UTC).astimezone(BERLIN):%H:%M %z}")
print("\n=== 2. ⚠️ Kuz: 25-oktabr, Berlin ===")
for fold in (0, 1):
d = datetime(2026, 10, 25, 2, 30, fold=fold, tzinfo=BERLIN)
print(f" 02:30 fold={fold}: siljish={d:%z}, UTC={d.astimezone(UTC):%H:%M}, ikki ma'noli={ikki_manolimi(d)}")
birinchi = datetime(2026, 10, 25, 2, 30, fold=0, tzinfo=BERLIN)
ikkinchi = birinchi.replace(fold=1)
print(f" birinchi == ikkinchi: {birinchi == ikkinchi} ← bir xil tzinfo: devor soati solishtirildi")
print(f" ikkinchi - birinchi: {ikkinchi - birinchi}")
print(f" UTC da farq: {ikkinchi.astimezone(UTC) - birinchi.astimezone(UTC)}")
print("\n=== 3. UTC dan soatma-soat: kuzgi kecha ===")
boshlanish = datetime(2026, 10, 24, 23, 30, tzinfo=UTC)
for i in range(4):
u = boshlanish + timedelta(hours=i)
m = u.astimezone(BERLIN)
print(f" UTC {u:%H:%M} → Berlin {m:%H:%M} {m:%z} fold={m.fold}")
print(" ⭐ UTC da hech narsa takrorlanmaydi — shuning uchun saqlash UTC da")
print("\n=== 4. Toshkentda bunday muammo yo'q ===")
for oy, kun in ((3, 29), (10, 25)):
d = datetime(2026, oy, kun, 2, 30, tzinfo=TOSHKENT)
print(f" {d:%d.%m %H:%M}: mavjud={mavjudmi(d)}, ikki ma'noli={ikki_manolimi(d)}")
print("\n=== 5. Siyosat: foydalanuvchi mavjud bo'lmagan vaqt tanlasa ===")
def tuzat(d: datetime) -> tuple[datetime, str]:
if not mavjudmi(d):
return d.astimezone(UTC).astimezone(d.tzinfo), "surildi (bo'shliq)"
if ikki_manolimi(d):
return d.replace(fold=0), "birinchisi tanlandi (takror)"
return d, "o'zgarishsiz"
for d in (datetime(2026, 3, 29, 2, 15, tzinfo=BERLIN),
datetime(2026, 10, 25, 2, 15, tzinfo=BERLIN),
datetime(2026, 9, 17, 2, 15, tzinfo=BERLIN)):
natija, izoh = tuzat(d)
print(f" {d:%d.%m %H:%M} → {natija:%d.%m %H:%M %z} {izoh}")
if __name__ == "__main__":
main()Natijaning muhim qismi:
=== 1. ⚠️ Bahor: 29-mart, Berlin ===
01:30 siljish=+0100 mavjud=True UTC=00:30
02:00 siljish=+0100 mavjud=False UTC=01:00
02:30 siljish=+0100 mavjud=False UTC=01:30
03:00 siljish=+0200 mavjud=True UTC=01:00
03:30 siljish=+0200 mavjud=True UTC=01:30
02:30 xato bermadi, UTC orqali qaytganda: 03:30 +0200
=== 2. ⚠️ Kuz: 25-oktabr, Berlin ===
02:30 fold=0: siljish=+0200, UTC=00:30, ikki ma'noli=True
02:30 fold=1: siljish=+0100, UTC=01:30, ikki ma'noli=True
birinchi == ikkinchi: True ← bir xil tzinfo: devor soati solishtirildi
ikkinchi - birinchi: 0:00:00
UTC da farq: 1:00:00
=== 3. UTC dan soatma-soat: kuzgi kecha ===
UTC 23:30 → Berlin 01:30 +0200 fold=0
UTC 00:30 → Berlin 02:30 +0200 fold=0
UTC 01:30 → Berlin 02:30 +0100 fold=1
UTC 02:30 → Berlin 03:30 +0100 fold=0
⭐ UTC da hech narsa takrorlanmaydi — shuning uchun saqlash UTC da
=== 4. Toshkentda bunday muammo yo'q ===
29.03 02:30: mavjud=True, ikki ma'noli=False
25.10 02:30: mavjud=True, ikki ma'noli=False
=== 5. Siyosat: foydalanuvchi mavjud bo'lmagan vaqt tanlasa ===
29.03 02:15 → 29.03 03:15 +0200 surildi (bo'shliq)
25.10 02:15 → 25.10 02:15 +0200 birinchisi tanlandi (takror)
17.09 02:15 → 17.09 02:15 +0200 o'zgarishsizNima ko'rsatdi: 2.4-bo'lim.
Misol 3 — Arifmetika: devor soati va haqiqiy vaqt
"""Bir zona ichida +1 kun va +24 soat farqi; ayirma devor soati bo'yicha; haqiqiy davomiylik UTC da; muddat va eslatma uchun to'g'ri tanlov."""
from datetime import UTC, datetime, timedelta
from zoneinfo import ZoneInfo
BERLIN = ZoneInfo("Europe/Berlin")
NYU_YORK = ZoneInfo("America/New_York")
def haqiqiy_farq(a: datetime, b: datetime) -> timedelta:
return a.astimezone(UTC) - b.astimezone(UTC)
def main() -> None:
print("=== 1. ⚠️ Bahorgi o'tish atrofida ===")
s = datetime(2026, 3, 28, 12, 0, tzinfo=BERLIN)
bir_kun = s + timedelta(days=1)
yigirma_tort = (s.astimezone(UTC) + timedelta(hours=24)).astimezone(BERLIN)
print(f" boshlanish: {s}")
print(f" + timedelta(days=1): {bir_kun} (haqiqatda {haqiqiy_farq(bir_kun, s)})")
print(f" UTC da + 24 soat: {yigirma_tort} (haqiqatda {haqiqiy_farq(yigirma_tort, s)})")
print(f" bir_kun - s (bir zona): {bir_kun - s} ⚠️")
print("\n=== 2. Kuzgi o'tish atrofida ===")
s = datetime(2026, 10, 24, 12, 0, tzinfo=BERLIN)
bir_kun = s + timedelta(days=1)
print(f" + 1 kun: {bir_kun}, devor soati farqi {bir_kun - s}, haqiqiy {haqiqiy_farq(bir_kun, s)}")
print("\n=== 3. Turli zonalar orasida ayirma — to'g'ri ===")
ketish = datetime(2026, 3, 28, 22, 0, tzinfo=BERLIN)
kelish = datetime(2026, 3, 29, 1, 30, tzinfo=NYU_YORK)
print(f" Berlin 28.03 22:00 → Nyu-York 29.03 01:30: parvoz {kelish - ketish}")
print(f" UTC orqali: {haqiqiy_farq(kelish, ketish)}")
print("\n=== 4. Qaysi holatda qaysi usul ===")
tuzilgan = datetime(2026, 3, 28, 9, 0, tzinfo=BERLIN)
token_muddati = tuzilgan.astimezone(UTC) + timedelta(hours=24)
ertangi_uchrashuv = tuzilgan + timedelta(days=1)
print(f" kirish tokeni (24 soat): {token_muddati.astimezone(BERLIN):%d.%m %H:%M %z}")
print(f" ertangi uchrashuv (shu vaqt): {ertangi_uchrashuv:%d.%m %H:%M %z}")
print(f" token aynan 24 soat: {haqiqiy_farq(token_muddati, tuzilgan) == timedelta(hours=24)}")
print(f" uchrashuv mahalliy 09:00 da: {ertangi_uchrashuv.hour == 9}")
print("\n=== 5. Bir yillik ish soati hisobi ===")
yil_boshi = datetime(2026, 1, 1, tzinfo=BERLIN)
yil_oxiri = datetime(2027, 1, 1, tzinfo=BERLIN)
print(f" devor soati bo'yicha: {(yil_oxiri - yil_boshi).total_seconds() / 3600:.0f} soat")
print(f" haqiqiy: {haqiqiy_farq(yil_oxiri, yil_boshi).total_seconds() / 3600:.0f} soat")
print(" ⭐ yil davomida bir soat yo'qolib, bir soat qaytgani uchun jami teng")
bahor = datetime(2026, 3, 1, tzinfo=BERLIN)
kuz = datetime(2026, 10, 1, tzinfo=BERLIN)
print(f" 1-mart → 1-oktabr: devor soati {(kuz - bahor).total_seconds() / 3600:.0f}, "
f"haqiqiy {haqiqiy_farq(kuz, bahor).total_seconds() / 3600:.0f} soat")
if __name__ == "__main__":
main()Natijaning muhim qismi:
=== 1. ⚠️ Bahorgi o'tish atrofida ===
boshlanish: 2026-03-28 12:00:00+01:00
+ timedelta(days=1): 2026-03-29 12:00:00+02:00 (haqiqatda 23:00:00)
UTC da + 24 soat: 2026-03-29 13:00:00+02:00 (haqiqatda 1 day, 0:00:00)
bir_kun - s (bir zona): 1 day, 0:00:00 ⚠️
=== 2. Kuzgi o'tish atrofida ===
+ 1 kun: 2026-10-25 12:00:00+01:00, devor soati farqi 1 day, 0:00:00, haqiqiy 1 day, 1:00:00
=== 3. Turli zonalar orasida ayirma — to'g'ri ===
Berlin 28.03 22:00 → Nyu-York 29.03 01:30: parvoz 8:30:00
UTC orqali: 8:30:00
=== 4. Qaysi holatda qaysi usul ===
kirish tokeni (24 soat): 29.03 10:00 +0200
ertangi uchrashuv (shu vaqt): 29.03 09:00 +0200
token aynan 24 soat: True
uchrashuv mahalliy 09:00 da: True
=== 5. Bir yillik ish soati hisobi ===
devor soati bo'yicha: 8760 soat
haqiqiy: 8760 soat
⭐ yil davomida bir soat yo'qolib, bir soat qaytgani uchun jami teng
1-mart → 1-oktabr: devor soati 5136, haqiqiy 5135 soatNima ko'rsatdi: 2.5-bo'lim.
Misol 4 — Amaliy: xalqaro jamoa uchun kundalik uchrashuvlar
Kirishdagi vaziyatni to'g'ri hal qilamiz. Uchrashuv Berlin vaqti bilan har kuni 09:00 da. Qoida: uchrashuv mahalliy vaqt + mintaqa nomi sifatida saqlanadi, har kun uchun UTC qayta hisoblanadi va har ishtirokchiga o'z mintaqasida ko'rsatiladi. Oxirida xato usul (UTC da +24 soat) bilan solishtiramiz.
"""Kalendar voqeasi: mahalliy vaqt + mintaqa; har kun UTC ni qayta hisoblash; ishtirokchilar mintaqasida ko'rsatish; xato usul bilan solishtirish."""
from dataclasses import dataclass
from datetime import UTC, date, datetime, time, timedelta
from zoneinfo import ZoneInfo
@dataclass(frozen=True, slots=True)
class Uchrashuv:
nom: str
mahalliy_vaqt: time
mintaqa: str
def lahza(self, kun: date) -> datetime:
zona = ZoneInfo(self.mintaqa)
d = datetime.combine(kun, self.mahalliy_vaqt, tzinfo=zona)
return d.astimezone(UTC) # saqlash va eslatma uchun
ISHTIROKCHILAR = {
"Aziz (Toshkent)": "Asia/Tashkent",
"Anna (Berlin)": "Europe/Berlin",
"John (Nyu-York)": "America/New_York",
}
def main() -> None:
uchrashuv = Uchrashuv("Kundalik stendap", time(9, 0), "Europe/Berlin")
kunlar = [date(2026, 3, 27) + timedelta(days=i) for i in range(4)]
print(f"=== 1. {uchrashuv.nom}: {uchrashuv.mahalliy_vaqt:%H:%M} {uchrashuv.mintaqa} ===")
sarlavha = " sana UTC " + " ".join(f"{n:16}" for n in ISHTIROKCHILAR)
print(sarlavha)
for kun in kunlar:
utc = uchrashuv.lahza(kun)
qator = " ".join(f"{utc.astimezone(ZoneInfo(z)):%H:%M %z}".ljust(16) for z in ISHTIROKCHILAR.values())
print(f" {kun:%d.%m.%Y} {utc:%H:%M} {qator}")
print("\n=== 2. Tekshiruvlar ===")
berlinda = [uchrashuv.lahza(k).astimezone(ZoneInfo("Europe/Berlin")).time() for k in kunlar]
print(f" Berlinda har kuni 09:00: {all(t == time(9, 0) for t in berlinda)}")
toshkentda = sorted({f"{uchrashuv.lahza(k).astimezone(ZoneInfo('Asia/Tashkent')):%H:%M}" for k in kunlar})
print(f" Toshkentda vaqt o'zgardi: {toshkentda}")
utclar = [uchrashuv.lahza(k) for k in kunlar]
oraliqlar = [str(b - a) for a, b in zip(utclar, utclar[1:])]
print(f" UTC dagi oraliqlar: {oraliqlar}")
print("\n=== 3. ⚠️ Xato usul: birinchi lahzaga +24 soat ===")
birinchi = uchrashuv.lahza(kunlar[0])
for i, kun in enumerate(kunlar):
xato = (birinchi + timedelta(hours=24 * i)).astimezone(ZoneInfo("Europe/Berlin"))
togri = uchrashuv.lahza(kun).astimezone(ZoneInfo("Europe/Berlin"))
belgi = "✅" if xato == togri else "❌"
print(f" {belgi} {kun:%d.%m}: xato usul {xato:%H:%M}, to'g'ri {togri:%H:%M}")
print("\n=== 4. Nyu-Yorkdagi o'tish (8-mart va 1-noyabr) atrofida ===")
nyu_york_uchrashuvi = Uchrashuv("Hisobot", time(8, 30), "America/New_York")
for kun in (date(2026, 3, 7), date(2026, 3, 9), date(2026, 10, 31), date(2026, 11, 2)):
utc = nyu_york_uchrashuvi.lahza(kun)
print(f" {kun:%d.%m}: Nyu-York 08:30 = Toshkent {utc.astimezone(ZoneInfo('Asia/Tashkent')):%H:%M}")
print("\n=== 5. Qoidalar ===")
print(" ✅ kelajakdagi kalendar voqeasi: mahalliy vaqt + IANA mintaqa nomi")
print(" ✅ aniq lahza (eslatma yuborish): har kun UTC ga qayta hisoblash")
print(" ✅ ko'rsatish: har ishtirokchining o'z mintaqasida")
print(" ❌ bitta UTC lahzaga +24 soat qo'shib borish")
if __name__ == "__main__":
main()Natijaning muhim qismi:
=== 1. Kundalik stendap: 09:00 Europe/Berlin ===
sana UTC Aziz (Toshkent) Anna (Berlin) John (Nyu-York)
27.03.2026 08:00 13:00 +0500 09:00 +0100 04:00 -0400
28.03.2026 08:00 13:00 +0500 09:00 +0100 04:00 -0400
29.03.2026 07:00 12:00 +0500 09:00 +0200 03:00 -0400
30.03.2026 07:00 12:00 +0500 09:00 +0200 03:00 -0400
=== 2. Tekshiruvlar ===
Berlinda har kuni 09:00: True
Toshkentda vaqt o'zgardi: ['12:00', '13:00']
UTC dagi oraliqlar: ['1 day, 0:00:00', '23:00:00', '1 day, 0:00:00']
=== 3. ⚠️ Xato usul: birinchi lahzaga +24 soat ===
✅ 27.03: xato usul 09:00, to'g'ri 09:00
✅ 28.03: xato usul 09:00, to'g'ri 09:00
❌ 29.03: xato usul 10:00, to'g'ri 09:00
❌ 30.03: xato usul 10:00, to'g'ri 09:00
=== 4. Nyu-Yorkdagi o'tish (8-mart va 1-noyabr) atrofida ===
07.03: Nyu-York 08:30 = Toshkent 18:30
09.03: Nyu-York 08:30 = Toshkent 17:30
31.10: Nyu-York 08:30 = Toshkent 17:30
02.11: Nyu-York 08:30 = Toshkent 18:30
=== 5. Qoidalar ===
✅ kelajakdagi kalendar voqeasi: mahalliy vaqt + IANA mintaqa nomi
✅ aniq lahza (eslatma yuborish): har kun UTC ga qayta hisoblash
✅ ko'rsatish: har ishtirokchining o'z mintaqasida
❌ bitta UTC lahzaga +24 soat qo'shib borishNima ko'rsatdi: 2.5, 2.7-bo'limlar.
5. To'g'ri va noto'g'ri tushunishlar
| Noto'g'ri fikr | To'g'risi |
|---|---|
"+05:00 — Toshkent mintaqasi" |
Faqat siljish; mintaqa — Asia/Tashkent |
"ZoneInfo hamma joyda ishlaydi" |
Windows va slim konteynerlarda tzdata kerak |
"replace(tzinfo=...) mintaqaga o'giradi" |
Yopishtiradi — boshqa lahza bo'lib qoladi |
| "Mavjud bo'lmagan vaqt xato beradi" | Jim yaratiladi |
| "Bir zonadagi ikki vaqt ayirmasi — haqiqiy davomiylik" | Devor soati farqi |
"timedelta(days=1) = 24 soat" |
Yozgi vaqt o'tishida 23 yoki 25 soat |
| "Kelajakdagi voqeani UTC da saqlash yetarli" | Qoidalar o'zgarishi mumkin — mahalliy vaqt + mintaqa |
| "O'zbekistonda bu muammolar yo'q" | Hamkorlar, serverlar va foydalanuvchilar boshqa mintaqada |
6. Keng tarqalgan xatolar va yechimlari
1. Siljishni mintaqa sifatida saqlash
foydalanuvchi.mintaqa = "+01:00" # ❌
foydalanuvchi.mintaqa = "Europe/Berlin" # ✅2. replace bilan o'girish
utc_vaqt.replace(tzinfo=TOSHKENT) # ❌ 5 soat siljidi
utc_vaqt.astimezone(TOSHKENT) # ✅3. Naive vaqtni astimezone qilish
datetime(2026, 9, 17, 14).astimezone(UTC) # ⚠️ server mintaqasiga bog'liq
datetime(2026, 9, 17, 14, tzinfo=TOSHKENT).astimezone(UTC) # ✅4. Takroriy voqeani UTC da qo'shish
keyingi = oldingi_utc + timedelta(days=1) # ❌ yozgi vaqtda siljiydi
keyingi = datetime.combine(kun, vaqt, tzinfo=zona).astimezone(UTC) # ✅5. Davomiylikni bir zona ichida ayirish
davom = tugash_berlin - boshlanish_berlin # ⚠️ devor soati
davom = tugash_berlin.astimezone(UTC) - boshlanish_berlin.astimezone(UTC) # ✅6. tzdata ni bog'liqliklarga qo'shmaslik
# ❌ Linux'da ishlaydi, Windows/Docker slim'da ZoneInfoNotFoundError
# ✅ pyproject.toml
dependencies = ["tzdata"]7. Foydalanuvchi tanlagan vaqtni tekshirmaslik
# ⚠️ 29-mart 02:30 Berlin — mavjud emas
if not mavjudmi(tanlangan): ... # ✅ surish yoki ogohlantirish8. Server vaqtiga tayanish
datetime.now() # ❌ server qayerda?
datetime.now(UTC) # ✅7. Integratsiya — bu bilim qayerda kerak bo'ladi
- 15.4-dars (o'tilgan):
datetimeturlari va arifmetika - 15.16-dars:
logging— jurnallarda UTC vaqt belgilari - 16.2-dars: JSON da ISO 8601 bilan saqlash
- 17-qism: yozgi vaqt o'tish kunlari uchun testlar
- 20.6-dars: so'rov va javob — API da vaqtni qabul qilish va qaytarish
- 23-qism: PostgreSQL
timestamptzvaAT TIME ZONE - 26-qism: cron va rejalashtirilgan vazifalar mintaqalari
8. Eng yaxshi amaliyotlar
Saqlash — aware UTC.
Foydalanuvchi profilida — IANA mintaqa nomi.
Ko'rsatishda —
astimezone(ZoneInfo(...)).Kelajakdagi kalendar voqealari — mahalliy vaqt + mintaqa, UTC har safar hisoblanadi.
Muddat va taymerlar — UTC +
timedelta.tzdatani bog'liqliklarga qo'shing va muntazam yangilang.Yozgi vaqt o'tish kunlarini testlarga kiriting — bo'shliq va takror uchun.
Naive
datetimeni tizim chegarasidan ichkariga o'tkazmang.
9. Amaliy topshiriq
Vazifa 1: Natijani bashorat qiling
from datetime import UTC, datetime, timedelta, timezone
from zoneinfo import ZoneInfo
T, B = ZoneInfo("Asia/Tashkent"), ZoneInfo("Europe/Berlin")
1. print(datetime(2026, 9, 17, 9, tzinfo=UTC).astimezone(T).hour)
2. print(datetime(2026, 9, 17, 14, tzinfo=T) == datetime(2026, 9, 17, 9, tzinfo=UTC))
3. print(datetime(2026, 1, 15, 12, tzinfo=B).utcoffset())
4. print(datetime(2026, 7, 15, 12, tzinfo=B).utcoffset())
5. print(datetime(2026, 9, 17, 14, tzinfo=T).replace(tzinfo=UTC).hour)
6. print(str(T))
7. print(datetime(2026, 7, 1, tzinfo=T).dst())
8. print(datetime(2026, 10, 25, 2, 30, fold=1, tzinfo=B).utcoffset())
9. print(datetime(2026, 3, 29, 12, tzinfo=B) - datetime(2026, 3, 28, 12, tzinfo=B))
10. print(datetime.fromisoformat("2026-09-17T14:00+05:00").tzinfo == timezone(timedelta(hours=5)))
11. print(ZoneInfo("Asia/Tashkent") is T)
12. print(datetime(1990, 7, 1, 12, tzinfo=T).utcoffset())Javoblar
14True— turlitzinfo, UTC bo'yicha solishtiriladi1:00:002:00:0014—replacefaqat yopishtiradiAsia/Tashkent0:00:001:00:001 day, 0:00:00— devor soati bo'yichaTrueTrue— kesh7:00:00
Vazifa 2: Xatolarni tuzating
1. def korsat(utc_vaqt, mintaqa):
return utc_vaqt.replace(tzinfo=ZoneInfo(mintaqa))
2. def keyingi_eslatma(oxirgi_utc):
return oxirgi_utc + timedelta(days=7) # har dushanba 09:00 Toshkent vaqti
3. def davomiylik(boshlanish, tugash): # ikkalasi Europe/Berlin
return tugash - boshlanish
4. class Foydalanuvchi:
mintaqa: str = "+05:00"
5. def saqlash_vaqti():
return datetime.now().isoformat()Javoblar
1. def korsat(utc_vaqt, mintaqa):
return utc_vaqt.astimezone(ZoneInfo(mintaqa))
2. def keyingi_eslatma(oxirgi_kun: date) -> datetime:
kun = oxirgi_kun + timedelta(days=7)
mahalliy = datetime.combine(kun, time(9, 0), tzinfo=ZoneInfo("Asia/Tashkent"))
return mahalliy.astimezone(UTC)
# Toshkentda yozgi vaqt yo'q, lekin qoida mintaqa almashsa ham to'g'ri qoladi
3. def davomiylik(boshlanish, tugash):
return tugash.astimezone(UTC) - boshlanish.astimezone(UTC)
4. class Foydalanuvchi:
mintaqa: str = "Asia/Tashkent"
5. def saqlash_vaqti():
return datetime.now(UTC).isoformat()Vazifa 3: Yozgi vaqt o'tishlarini topish
otishlar(mintaqa, yil) funksiyasini yozing:
- Yil davomida siljish o'zgargan barcha lahzalarni toping (soatma-soat UTC bo'ylab, keyin daqiqagacha aniqlashtiring)
- Har o'tish uchun: sana, eski va yangi siljish, bo'shliq yoki takror
Europe/Berlin,America/New_York,Australia/Sydney,Asia/Tashkentuchun ishga tushiringAustralia/Sydneyda o'tishlar nega "teskari" ekanini tushuntiringAsia/Tashkentuchun 1981–1992 yillar tarixini jadval qiling
Vazifa 4: Dunyo soati
- Foydalanuvchi kiritgan mintaqalar ro'yxati uchun hozirgi vaqtni ko'rsating (
hozirparametr orqali) - Toshkentga nisbatan farq:
"+3 soat","-10 soat","+5:30" - Har shahar uchun "ish vaqti" (09:00–18:00) ichidami — belgi bilan
- Hamma uchun qulay uchrashuv soatini toping (Toshkent vaqtida)
Vazifa 5: Takroriy voqealar
takrorlash(boshlanish_mahalliy, mintaqa, qoida, soni):
- Qoidalar:
"kunlik","haftalik","har oy 31-kuni"(15.4-darsdagi qisish bilan) - Har voqea uchun UTC lahza va mahalliy vaqt
- Mavjud bo'lmagan vaqt — keyingi mavjud vaqtga surilsin, takrorlanuvchi — birinchisi
Europe/Berlinda mart va oktabrni o'z ichiga olgan sinovlar
Vazifa 6: Jurnallarni birlashtirish
Uch serverdan jurnallar: biri UTC, biri +05:00 siljishli, biri naive (lekin America/New_York vaqtida yozilgan ekani ma'lum):
- Hammasini aware UTC ga keltiring
- Kuzgi takror soatidagi naive yozuvlar uchun
foldni ketma-ketlik tartibidan aniqlang - Birlashtirilgan jurnalni vaqt bo'yicha saralang
- Tartib buzilgan joylarni (soat noto'g'ri) aniqlang
Vazifa 7: O'ylash
Ko'p davlatlar yozgi vaqtdan voz kechmoqda (O'zbekiston — 1992, Rossiya — 2014, Yevropa Ittifoqi muhokama qilmoqda). Agar mamlakat qoidani e'lon qilingandan bir necha hafta o'tib o'zgartirsa, dasturiy tizimlarda nima sodir bo'ladi? UTC da saqlangan kelajakdagi uchrashuvlar bilan nima bo'ladi va tzdata yangilanishi nega muhim?
Javob
Qisqa javob: Mintaqa qoidalari — dasturiy ta'minot uchun tashqi, o'zgaruvchan ma'lumot. Qoida o'zgarsa, tzdata yangilanmagan tizimlar noto'g'ri vaqt ko'rsatadi, kelajakdagi voqealarni UTC da saqlagan tizimlar esa foydalanuvchi kutgan mahalliy vaqtni yo'qotadi. Shuning uchun kelajakdagi kalendar voqealari "mahalliy vaqt + mintaqa" sifatida saqlanadi va tzdata muntazam yangilanadi.
1. IANA tz ma'lumotlar bazasi
- Ko'ngillilar tomonidan yuritiladi, yiliga bir necha marta yangilanadi (masalan,
2026d— 2026-yilning 4-versiyasi) - Operatsion tizimlar, brauzerlar, Java, Python
tzdata, PostgreSQL — hammasi undan nusxa oladi - Har nusxa alohida yangilanadi — bitta tizimda bir necha xil versiya bo'lishi mumkin
2. Qisqa ogohlantirish bilan o'zgarish
| Qatlam | Nima bo'ladi |
|---|---|
Eski tzdata li server |
Eski qoida bo'yicha hisoblaydi — 1 soat xato |
| Mobil qurilmalar | OS yangilanishini kutadi |
| Brauzerdagi JavaScript | Brauzer versiyasiga bog'liq |
Baza (timestamptz) |
O'z tz nusxasiga bog'liq |
Natija: bir xil voqea turli tizimlarda turli vaqtda ko'rinadi.
3. UTC da saqlangan kelajakdagi voqea
Uchrashuv: "2027-yil 1-aprel, 09:00, Europe/Berlin" — yaratilgan paytdagi qoida bo'yicha 07:00 UTC saqlandi.
Agar Yevropa Ittifoqi yozgi vaqtni bekor qilsa va Berlin doimiy +01:00 da qolsa:
- UTC da saqlangan:
07:00 UTC→ yangi qoidada Berlinda 08:00 — foydalanuvchi 09:00 ni kutgan edi - Mahalliy vaqt + mintaqa saqlangan:
09:00 Europe/Berlin→ yangitzdatabilan08:00 UTCqayta hisoblanadi
| Voqea turi | Saqlash |
|---|---|
| O'tgan voqea (to'lov, kirish) | UTC — bu fakt, o'zgarmaydi |
| Kelajakdagi kalendar voqeasi | Mahalliy vaqt + mintaqa (+ keshlangan UTC) |
| Muddat, taymer ("24 soatdan keyin") | UTC — fizik vaqt |
4. Muhandislik amaliyoti
tzdatani bog'liqlik sifatida qo'shing va CI da yangilanishini kuzating- Kelajakdagi voqealar uchun UTC ni kesh deb hisoblang:
tzdatayangilanganda qayta hisoblang - Mijoz va server bir xil mintaqa qoidalaridan foydalanayotganini tekshiring (masalan, API javobida UTC va mintaqa nomini birga bering)
- Muhim tizimlarda (aviatsiya, moliya) — mintaqa ma'lumotlari versiyasini jurnalga yozing
5. Xulosa
- Vaqt mintaqasi — fizika emas, siyosat
- Qoidalar o'zgaradi, ba'zan bir necha haftalik ogohlantirish bilan
- O'tgan voqealar — UTC; kelajakdagi kalendar voqealari — mahalliy vaqt + mintaqa
tzdata— ilovaning boshqa bog'liqliklari kabi yangilanishi shart bo'lgan qism
Nimani mustahkamlaydi: 2.1–2.7-bo'limlar.
Xulosa
Bu darsda vaqt mintaqalari bilan ishlashni va yozgi vaqt tuzoqlarini o'rgandik.
Eng muhim uch fikr:
Siljish — mintaqa emas.
+01:00faqat bitta lahzadagi farq;Europe/Berlinesa qoidalar tarixini biladi. ISO satrdan o'qilgan qat'iy siljish bilan olti oy keyingi vaqtni hisoblash bir soat xato beradi. Profilda mintaqa nomi saqlanadi,zoneinfobilan ishlatiladi; Windows va slim konteynerlarda buning uchuntzdatapaketi kerak.astimezoneo'giradi,replace(tzinfo=...)esa faqat yopishtiradi.Yozgi vaqt: bo'shliq, takror va
fold. Bahorda ba'zi devor soatlari mavjud emas — lekindatetimexato bermaydi, UTC orqali qaytganda boshqa vaqtga aylanadi. Kuzda bir soat ikki marta keladi vafold=0/1bilan farqlanadi; bir xiltzinfoli ikki shunday vaqt==bo'yicha teng, ayirmasi0, UTC da esa bir soat farq qiladi.Arifmetika: devor soati yoki haqiqiy vaqt — ongli tanlov. Bir mintaqa ichida
+ timedelta(days=1)devor soatini saqlaydi (o'tish kuni 23 yoki 25 soat), ayirma ham devor soati farqini beradi. Haqiqiy davomiylik va muddatlar — UTC da; takroriy uchrashuvlar — mahalliy vaqt + mintaqa bo'yicha har kun qayta hisoblanadi. UTC da+24 soatqo'shib borish esa hamkorlar uchun uchrashuvni bir soatga siljitadi.
Keyingi darsda collections moduliga o'tamiz: Counter va defaultdict — sanash va guruhlashning eng qulay vositalari.
Izohlar (0)
Izoh yozish uchun kiring.
- Hozircha izoh yo'q. Birinchi bo'ling!