Fülöp Dénes

Fülöp Dénes

  · 7 min read

Hogyan okozhat az időátállítás hibás késési számítást?

Téged is meglepett ami nemrég egy nagy magyarországi vállalatnál megtörtént? A cikkből kiderül mi eredményezhet hibás számítási következtetéseket.

Téged is meglepett ami nemrég egy nagy magyarországi vállalatnál megtörtént? A cikkből kiderül mi eredményezhet hibás számítási következtetéseket.

Bevezető

Képzeld el, hogy egy vasárnap hajnalban a rendszered hirtelen elkezd kompenzációkat fizetni az ügyfeleknek — teljesen indokolatlanul. Nincs leállás, nincs teljesítményprobléma, minden szolgáltatás rendben működik … mégis nő a “késések” száma.

A hiba oka? Időátállítás.

Ha a rendszeredben késés alapján pénzügyi kompenzáció jár (például 30 perc felett), akkor az óraátállítás könnyen hamis eredményeket generálhat. Ebben a cikkben utánnajártam, hogy:

  • miért történik ez,
  • hol csúszik el a legtöbb rendszer,
  • és hogyan lehet ezt teljesen biztonságosan kezelni production környezetben is.

Mi az időátállítás és miért probléma?

Magyarországon (és Európa nagy részén) évente kétszer történik óraátállítás:

Hogyan számoljunk helyesen késést időátállításkor – tavaszi és őszi órállítás időpontja
Ábra 1: A nyári időszámítás előreállítás: 2 -> 3 és a téli időszámítás visszaállítás: 3 -> 2
  • tavasszal: az óra előre ugrik (02:00 —> 03:00)
  • ősszel: az óra visszaáll (03:00 —> 02:00)

Ez első ránézésre ártalmatlannak tűnik, de van egy kritikus következménye:

  • A “helyi idő” (local time) nem folytonos.

Mit jelent ez a gyakorlatban?

Tavasszal bizonyos időpontok nem léteznek (pl. 02:30 egyszerűen kimarad).

A helyi idővel, a probléma pld:

Közép-európai idő (CET→CEST) Helyi idő szerint 02:00-kor az órák 03:00-ra ugrik. A 02:00–03:00 közötti időpontok nem léteznek helyi idő szerint.

Ősszel bizonyos időpontok kétszer léteznek (pl. 02:30 két különböző valós időpontot jelent).

Ez a kettő együtt garantáltan problémát okoz minden olyan rendszerben, ahol időalapú számítás alapján üzleti döntés születik.

Több időzóna típus is használatban van

Ha nem figyelünk arra, hogy egységes UTC alapú időzonát használjunk akár abba a hibába is belefuthatunk, hogy eltérő időzonákat próbálunk összehasonlítani egy felépített rendszeren belül.

Főbb, meghatározóbb időzóna típusok:

IdőzónaTeljes névKapcsolat az UTC/GMT-velMikor használatos
UTCKoordinált világidőUTC+0Egész évben
GMTGreenwichi középidőUTC+0Egész évben
CETKözép-európai időUTC+1Téli idő (standard)
CESTKözép-európai nyári időUTC+2Nyári idő (DST)
Hogyan számoljunk helyesen késést időátállításkor – UTC időzónák térképe
Ábra 2: UTC időzónák térképe

Érdemes tisztába lenni és utánna olvasni, hogy bizonyos programozási nyelvek melyik időzonát támogatják, mit vesznek számítási alapúl, pld:

A zoneinfo a Python 3.9+ verziójából származik. Automatikusan kezeli a CET/CEST váltást.

A ZonedDateTime a Java-ban automatikusan kezeli a nyári időszámítás átmeneteit.

A klasszikus hiba: local time alapú számítás

Összeszedtem a teszteseteket amik segítenek lefedni a legfontosabb eseteket és megmutatja, hogy mire is kell figyelni ilyenkor.

Tesztesetek időátállás nélküli időpontokban:

IDForgatókönyvIndulásÉrkezésVárható késésKompenzáció?
TC-01Pontban érkezik10:0010:000 percNem
TC-0229 perces késés10:0010:2929 percNem
TC-03Pontosan 30 perces késés10:0010:3030 percNem
TC-0431 perces késés10:0010:3131 percIgen
TC-05Nagy késés (2 óra)10:0012:00120 percIgen
TC-06Éjszakai késés23:4500:20 (+1 nap)35 percIgen

TC-03 javasolt tisztázni a fejlesztés időpontjában, hogy > 30 vagy >= 30.

Sok rendszerben a késést így számolják:

delay = actual_local_time - planned_time

Ez önmagában még nem probléma — a gond az, milyen időzónában történik a számítás.

Hibás példa (időátállításkor): tervezett idő: 01:50 —> tényleges idő: 03:10

A rendszer szerint a késés = 80 perc. —> a valóságban a késés = 20 perc.

Mi történt? A rendszer nem vette figyelembe, hogy közben az óra előre ugrott egy órát.

Következmény: Ha a szabály az, hogy: 30 perc késés után pénzügyi kompenzáció jár, akkor: a rendszer tévesen kompenzációt fizet, akár tömegesen, teljesen hibás üzleti döntés alapján.

Az alábbiakban felsorolom azokat a példákat ahol már vannak időátálással kapcsolatos teszt esetek is:

Tesztesetek tavaszi időátállással (órák +1 óra)

IDForgatókönyvÜtemezett (helyi)Valós érkezés (helyi)Valódi UTC késésKompenzáció?**DST kockázat
TC-07Indul a műszak előtt, érkezik a műszak után, 29 perces valós késés01:4503:0529 perc*NemMagas
TC-08Indul a műszak előtt, érkezik a műszak után, 31 perces valós késés01:4503:0731 perc*IgenMagas
TC-09Ütemezve a nem létező órára (02:30)02:3003:10N/AHibakezelésKritikus
TC-10Mindkét idő a műszak előtt01:0001:2929 percNemBiztonságos
TC-11Mindkét idő a műszak után03:0003:3131 percIgenBiztonságos
TC-12Pontosan a műszak kezdőhatárán01:5903:001 percNemMagas
TC-13Helyileg 90 perces késés látszik, de valós késés 30 perc01:3003:0030 percNemKritikus

*UTC időkülönbséget használtunk, nem helyi időkülönbséget

**DST (Daylight Saving Time) kockázat azt jelenti, hogy befolyásolhatja az időátállítás.

Tesztesetek téli időátállással (órák -1 óra)

IDForgatókönyvÜtemezett (helyi)Valódi érkezés (helyi)Valódi UTC késésKompenzáció?**DST kockázat
TC-14Indulás műszak előtt, érkezés az első 02:00–03:00 között01:3002:10 (1.)40 percIgenMagas
TC-15Indulás műszak előtt, érkezés a második 02:00–03:00 között01:3002:10 (2.)100 percIgenKritikus
TC-16Helyi késés 29 perc, valós késés 89 perc02:00 (1.)02:29 (2.)89 percIgenKritikus
TC-17Helyi és valós késés egyaránt 31 perc01:0001:3131 percIgenBiztonságos
TC-18Mindkét idő a megismételt órában (egyértelmű UTC)02:10 (1.)02:20 (1.)10 percNemMagas
TC-19Indulás az első előforduláskor, érkezés a másodiknál, 29 perc helyi = 89 perc valós02:30 (1.)02:59 (2.)89 percIgenKritikus
TC-20Mindkét idő a műszak után03:0003:3131 percIgenBiztonságos

*UTC időkülönbséget használtunk, nem helyi időkülönbséget

**DST (Daylight Saving Time) kockázat azt jelenti, hogy befolyásolhatja az időátállítás.

A helyes megoldás: UTC időzóna mindenek felett

A megoldás egyszerű, de sok rendszerben mégsem így működik:

Minden számítást UTC-ben kell végezni.

Minek a rövidítése az UTC?

Az UTC az Egyezményes Koordinált Világidő (Coordinated Universal Time / Temps Universel Coordonné) rövidítése. Ez a világ elsődleges időszabványa, amely atomórák alapján határozza meg a pontos időt. Nem egyezik meg teljesen a greenwichi idővel (GMT), és nem alkalmazza a nyári/téli óraátállítást.

A szemléltetés kedvért készítettem egy példát arra, hogy milyen eltérő formában vannak az időre vonatkozó adatok kezelve:

Hogyan számoljunk helyesen késést időátállításkor – Felhasználó, adatbázis, logika időzona verziók
Ábra 3: Felhasználó, adatbázis, logika időzona verziók

Alapelv:

  • Adattárolás → UTC
  • Backend logika → UTC
  • Megjelenítés → local time

Miért működik?

Az UTC idő:

  • nem tartalmaz időátállítást
  • folyamatos
  • egyértelmű

Így a következő számítás mindig helyes lesz:

delay = actual_utc - planned_utc

Függetlenül attól, hogy éppen történt-e óraátállítás vagy sem.

Hogyan implementáld (gyakorlatban)

  1. Időtárolás
  • Mindig UTC-ben tárold az időpontokat!
  • Használj ISO 8601 formátumot (pl. 2026-03-29T01:50:00Z)!
  • Kerüld a timezone nélküli datetime-eket!
  1. Backend logika

A kompenzáció számítása legyen egyértelmű és időzóna-független:

delay_minutes = (actual_utc - planned_utc).total_minutes

if delay_minutes >= 30:
    compensation = true

Semmilyen speciális DST (Daylight Saving Time) logika nem szükséges.

  1. Frontend megjelenítés
  • A felhasználók számára jeleníts meg helyi időt
  • Használd a megfelelő időzónát (pl. Europe/Budapest)
  • Fontos: ez csak vizualizáció, nem számítás

Az alábbi képen látható a kompenzáció státusza, ami korábbi képen megjelölt menetrendszerű érkezés és a tényleges érkezés időpontok közötti különbségből ered.

Hogyan számoljunk helyesen késést időátállításkor – A számolt eredmény és az eltérő idő formátumok
Ábra 4: A számolt eredmény és az eltérő idő formátumok

Edge case-ek, amik tönkretehetik a kialakított rendszert

Nem létező időpont (tavasz): pl. 02:30 nincs.

Mit tegyél? validáld a bevitt időpontokat vagy automatikusan igazítsd őket (pl. 03:00-ra).

Duplikált időpont (ősz): pl. 02:30 → két különböző időpont.

Megoldás: tárold az offsetet is (pl. +02:00 vs +01:00).

Az offset időszámításnál és technikai rendszerekben eltérést, elmozdulást vagy különbséget jelent egy alapértelmezett, kiindulási ponthoz (referenciapont) képest.

Határérték problémák: 29 vs 30 perc, kerekítési hibák, másodperc alapú eltérések. Megoldás: egységes kerekítési szabály, explicit definíció (>= 30 perc).

Tesztelés: amit kötelező lefedni

Ezek nélkül production bug lesz:

  • időátállítás előtti nap (pld. Alaprendszer helyességének ellenőrzése)
  • időátállítás pillanata (DST-kezelés kritikus tesztelése)
  • időátállítás utáni nap (Új offset helyes használatának ellenőrzése)
  • boundary esetek (29, 30, 31 perc késés) (Kompenzációs küszöb pontosságának ellenőrzése)
  • időzóna és több régióra kiterjedő tesztek
  • edge case és rendszertesztek

Időzóna és több régióra kiterjedő tesztek

IDForgatókönyvVárt eredményMegjegyzés
TC-21Jármű átlépi az időzóna határt az út soránHelyes UTC késésTároljuk az indulást/érkezést UTC-ben
TC-22Ütemezett UTC-ben, helyi időben jelenik megHelyes kompenzációUTC a mérvadó
TC-23Szerver más időzónában, mint a járműHelyes kompenzációMinden időbélyeg UTC-ben legyen
TC-24DST szabályok országonként eltérnek (pl. HU vs US)Helyes régió szerintHasználjuk az IANA időzóna adatbázist
TC-25Ország, ahol nem alkalmaznak nyári időszámítást (pl. Kína, India)Nincs DST problémaMégis UTC-t használjunk konzisztenciához

Edge Case és rendszertesztek

IDForgatókönyvVárt eredményMegjegyzés
TC-26Érkezés az indulás előtt, az adatbázisbanElutasítás / HibaSzükséges adatellenőrzés
TC-27Null vagy hiányzó időbélyegElutasítás / HibaNull-biztonság szükséges
TC-28Időbélyegek helyi időben tárolva az adatbázisbanTárolás javítása UTC-reArchitektúra szempont
TC-29Szökőmásodperc a késési időablakbanRendszer kezeli helyesenRitka, de előfordulhat
TC-30Késés pontosan 30 perc 0 mp 0 msHatárérték ellenőrzésPontosan definiálni > vs >=
TC-31Többnapos késés (jármű beragad)Helyes többnapos számításNincs túlcsordulás
TC-32Rendszeróra manuális változtatása a szerverenUTC nem érintettOS-szintű kérdés
TC-33DST átállás számítás közbenUTC eredmény helyesFő DST teszt

Kritikus Teszt Prioritások Összegzése

MUSZÁJ TESZTELNI (Legnagyobb kockázat)
  • TC-09 → Ütemezve a nem létező “tavaszi átállás” órában
  • TC-13 → Helyi idő 90 perc késést mutat, de a valós késés 30 perc (tavasz)
  • TC-16 → Helyi idő 29 perc késést mutat, de a valós késés 89 perc (ősz)
  • TC-19 → Kétszer előforduló óra okoz elmaradt kompenzációt
AJÁNLOTT TESZTELNI (Magas kockázat)
  • TC-07, TC-08 → Átlépés a tavaszi átállás óráján
  • TC-14, TC-15 → Érkezés az első vs. második ismétlődő órában
  • TC-23 → Szerver/jármű időzóna eltérés
JÓ LENNE TESZTELNI (Közepes kockázat)
  • TC-21 → Időzónákon átnyúló utak
  • TC-29 → Szökőmásodpercek
  • TC-31 → Többnapos késések

Mit NE csinálj (anti-patterns)

Tipikus hibák:

  • local time alapú különbség számítás
  • “DST hackek” (pl. -60 perc manuálisan)
  • hardcode-olt dátumok
  • timezone nélküli datetime használat
  • cron job-ok kritikus logikára local time-ban

Valós üzleti hatás

Ez nem csak technikai probléma. Ha rosszul kezeled az időt:

  • túlfizetsz kompenzációt
  • alulfizetsz (jogi kockázat)
  • audit során nem tudod bizonyítani a számítás helyességét

Jó gyakorlat

Logold:

  • planned idő (UTC)
  • actual idő (UTC)
  • timezone
  • számolt késés

Így minden döntés visszakövethető.

Összefoglalás

Az időátállítás önmagában nem probléma. A probléma az, ha a rendszered:

  • local time-ban számol vagy nem egyforma időzónát hasonlítasz össze!
  • nem kezeli a timezone-okat megfelelően

A legfontosabb tanulság:

Ha pénz múlik rajta, soha ne számolj local time-ban.

Használj UTC-t minden számításhoz, és az időátállítás többé nem fog meglepetést okozni.


Checklist (takeaway):

  1. Minden időbélyeget UTC-ben tároltál és az UTC-t az UTC-vel összehasonlítod össze? - check
  2. A kompenzációs küszöb világosan definiált? (pld > 30 perc vagy >= 30 perc) - check
  3. Nem létező helyi időket (tavaszi átállás) kezelted hiba nélkül? - check
  4. Kétértelmű helyi időket (őszi visszaállás) UTC offset alapján oldottad fel? - check
  5. Nincs helyi idő aritmetika — mindig UTC epoch milliszekundumot használtál? - check
  6. Minden időzóna konverzió IANA időzóna adatbázis alapján történik? (nem fix offsetek) - check

Nálatok volt már időátállításból eredő bug?

Mindenhol UTC-t használtok, ahol fontos üzleti vagy kompenzációval kapcsolatos döntések születnek vagy még vannak “legacy” megoldások?

Ha tetszett a cikk oszd meg másokkal is! Köszönöm!


Kérdésed van? Írj nekünk, és segítünk megtalálni a számodra ideális megoldásokat.

Vissza a cikkekhez