Időzónák webalkalmazásban: óraátállítás, időpontok és riportok

A webalkalmazásban rosszul kezelt időzónák főleg óraátállításkor okoznak gondot: az emlékeztető egy órával korábban érkezik, az ismétlődő időpont a nyári időszámításra való átállás után elcsúszik, és az átállás napjáról szóló napi riport nem egyezik a könyveléssel. A megoldás nem egyetlen szerverbeállítás, hanem világos szabály minden időadat-típusra. Az időpillanatokat tárolja UTC-ben, a helyi időben egyeztetett jövőbeli időpontokat dátumként, időként és időzónanévként, például Europe/Bratislava, az idő nélküli dátumokat dátumként, az ismétlődéseket pedig időzónával ellátott szabályként. Ezután célzottan tesztelje azokat a napokat, amikor átállítják az órát.

Ez nemcsak a külföldi ügyfelekkel dolgozó cégeket érinti. Elég egy foglalási rendszer, a szervizkiszállások ütemezése vagy egy éjszakai export a könyvelésbe. Szlovákiában is van évente egy 23 órás és egy 25 órás nap.

Miért tűnik el vagy ismétlődik meg egy óra óraátállításkor

Az Europe/Bratislava időzónában tavasszal 2:00-ról 3:00-ra állítják előre az órát, így a helyi 2:30 azon a napon nem létezik. Ősszel 3:00-ról 2:00-ra állítják vissza, és a 2:30 kétszer következik be: először +02:00, majd +01:00 UTC-eltolással. A jelenlegi szabályok szerint a következő tavaszi átállás 2027. március 28-ra, az őszi pedig 2027. október 31-re esik.

Ezeket a szabályokat nem a programozók találják ki. Az IANA időzóna-adatbázisa tartja nyilván őket, amelyet tz vagy zoneinfo néven is ismernek. Az IANA szerint az adatbázist rendszeresen frissítik, hogy kövesse az állami szervek döntéseit az időzónák határairól, az UTC-eltolásokról és a nyári időszámításról, a végfelhasználók pedig jellemzően a szoftverek és az operációs rendszerek frissítésein keresztül kapják meg. A változás közvetlenül a hatálybalépés előtt is érkezhet: a 2026. október 27-i 2026f kiadás rögzítette, hogy Kuba 2026. november 1-jén nem tér vissza a téli időszámításra.

A döntésekhez kulcsfontosságú két időfajta megkülönböztetése. Az időpillanat egy pont az idővonalon, például egy fizetés beérkezése vagy egy e-mail elküldése, és egyértelműen rögzíthető UTC-ben. A helyi időpont emberek közötti megállapodás, például egy kassai szervizlátogatás kedden 9:00-kor. Az UTC-hez való viszonyát az időpont napján érvényes időzóna-szabályok határozzák meg, nem az a nap, amikor valaki rögzítette.

Példa: egy szervizcég foglalásai

Szemléltető példa, nem egy konkrét ügyfél esete. Egy szervizcég webalkalmazásban ütemezi a technikusok kiszállásait, hétvégén is. Egy ügyfél januárban rendszeres ellenőrzést foglal minden keddre 9:00-ra. Az alkalmazás 24 órával az időpont előtt emlékeztetőt küld, éjszaka exportálja a lezárt munkákat a könyvelésbe, reggel pedig elküldi a vezetőnek az előző napi bevételek áttekintését.

Mentéskor a fejlesztő átszámította az időpontot UTC-re: januárban a 9:00 8:00 UTC. A nyári időszámításra való átállás után az alkalmazás továbbra is 8:00 UTC-re ütemez, ami azonban helyi idő szerint már 10:00. A technikus egy órával később érkezik, mint ahogy az ügyfél várja.

Más hibák csendesebbek. A 2027. március 28-án, vasárnap 9:00-kor kezdődő időpont „24 órával korábbi” emlékeztetője szombaton 8:00-kor megy ki, mert a két nap azonos órái között csak 23 óra telik el. A 2:30-ra ütemezett éjszakai export a tavaszi éjszakán talán el sem indul, az őszin pedig kétszer is lefuthat, attól függően, hogyan viselkedik az ütemező. Ha pedig a „tegnapi” riport a napot UTC szerint éjféltől éjfélig számolja, az télen szlovák idő szerint 1:00-kor, nyáron 2:00-kor kezdődik.

A javítás nem jelenti az egész alkalmazás újraírását. Az ismétlődő időpontot „minden kedden 9:00, Europe/Bratislava” szabályként kell tárolni, a cég eldönti, hogy az emlékeztető pontosan 24 órát vagy egy nappal korábbi azonos időpontot jelent-e, az exportot át kell tenni az éjszakai átállási órán kívülre, a riportot pedig a szlovák naptári nap szerint kell számolni.

Hogyan tárolja az egyes időadat-típusokat

A táblázat egyszerre szolgál a fejlesztőnek szóló specifikációként és a meglévő alkalmazás ellenőrzéseként. Az adatbázis minden oszlopának és az API minden mezőjének pontosan egy sorba kell tartoznia.

Adattípus Hogyan tárolja Példa
Esemény időpillanata Egy pont az időben, UTC-ben Fizetés beérkezése, bejelentkezés, bejegyzés az auditnaplóban
Jövőbeli helyi időpont Helyi dátum és idő, valamint az időzóna neve; az UTC csak származtatott érték Szervizlátogatás 2027. április 6-án 9:00-kor, Europe/Bratislava
Ismétlődő időpont Ismétlődési szabály, helyi kezdési idő és időzóna Minden kedden 9:00-kor
Idő nélküli dátum Csak dátum, idő és időzóna nélkül Számla fizetési határideje, szabadságnap
Személyhez, nem helyhez kötött idő Helyi idő időzóna nélkül, kifejezetten megjelölve Napi értesítés 8:00-kor ott, ahol a felhasználó éppen tartózkodik
Üzleti nap a riportokban Dátum és a cég időzónája; a nap határait UTC-re számítják át Bevételek 2026. október 25-én, egy 25 órás napon

Figyeljen arra, mit csinál az adatbázis. A PostgreSQL dokumentációja szerint a timestamp with time zone típusú értéket a rendszer belsőleg UTC-ben tárolja, az eredetileg megadott időzónát pedig nem őrzi meg. Ha a bemenet nem tartalmaz időzónát, az adatbázis a TimeZone beállítás szerinti zónát feltételezi, kiíráskor pedig az időt az éppen beállított zónára alakítja át. Időpillanatoknál ez helyes, a jövőbeli helyi időpontokhoz azonban külön oszlopban kell tárolni az időzóna nevét.

A személyhez kötött időre az iCalendar (RFC 5545) naptárszabvány az úgynevezett lebegő időt ismeri. Ez ugyanazt az órát jelenti, függetlenül attól, hogy az illető éppen melyik időzónában tartózkodik. Csak akkor használja, ha ez a szándék, ne a hiányzó időzóna pótlására.

Bevezetés egy meglévő alkalmazásban

1. Gyűjtse össze az összes időadatot

Nézze át az adatbázis oszlopait, az API mezőit, az importokat, az exportokat, az ütemezett feladatokat és a riportokat. Minden adatnál jegyezze fel a táblázat szerinti típusát és azt, honnan származik. A bizonytalan eseteket, például a tárolt időzóna nélküli időpontot, jelölje meg kiegészítésre.

2. Az időzóna nevét tárolja, ne fix eltolást

Időpontoknál, telephelyeknél és felhasználóknál az IANA időzóna nevét tárolja, például Europe/Bratislava. A +01:00 fix eltolás csak az év egy részében érvényes. Az RFC 9557 szabvány nyomatékosan nem javasolja, hogy időzóna helyett fix eltolást használjanak: egy januári értékből átvett eltolás hat hónap hozzáadása után egy órával elcsúszott eredményhez vezetne.

3. Egyértelműen küldje az időt az API-ban

Az API-ban az RFC 3339 formátumot használja UTC-eltolással, például 2027-04-06T09:00:00+02:00. Az RFC 9557 ezt a formátumot az időzóna nevét tartalmazó utótaggal bővíti, például 2027-04-06T09:00:00+02:00[Europe/Bratislava]. Helyi időpontoknál így a másik fél az időpillanatot és azt az időzónát is megkapja, amely szerint az időt tovább kell számolnia. Ha az utótagot nem érti, küldje az időzóna nevét külön mezőben. Ugyanezen szabvány szerint a küldő és a fogadó az időzóna-adatbázis különböző verzióit használhatja, ezért az integrációnak az ismeretlen időzónanevet is kezelnie kell.

4. A megfelelő időzónában jelenítse meg az időt

Ha az alkalmazás a böngészőben az Intl.DateTimeFormat segítségével formázza az időt, az MDN dokumentációja szerint a timeZone opció IANA időzónanevet fogad el, nélküle pedig annak a környezetnek az időzónája érvényes, amelyben a kód fut. Az az ügyfél, akinek a telefonja más időzónára van állítva, például szabadság alatt, így eltolva látná a szlovák szerviz időpontját. Döntse el, hogy az időpont a helyszín vagy a felhasználó időzónájában jelenjen-e meg, és az időzónát tüntesse fel az idő mellett.

5. Határozza meg a nem létező és a kétszer előforduló idő szabályait

Az iCalendar szabvány erre világos szabályokat ad: ha egy helyi idő kétszer fordul elő, az első előfordulása érvényes, ha pedig nem létezik, az átállás előtt érvényes eltolással kell értelmezni. A 2027. március 28-i, 2:30-ra szóló időpont így nyári idő szerint 3:30-ra esne. A szabvány arra is figyelmeztet, hogy egy ismétlődési szabály érvénytelen dátumot, például február 30-át, vagy nem létező helyi időt is előállíthat. Válasszon egyetlen viselkedést, rögzítse a specifikációban, és a foglalási űrlapon lehetőleg ne is kínáljon fel ilyen időpontokat.

6. Igazítsa át az ütemezett feladatokat és a riportokat

A technikai feladatokat, például a mentéseket vagy az exportokat, UTC szerint vagy az éjszakai átállási órán kívül ütemezze, és úgy tervezze meg őket, hogy egy ismételt futtatás ne hozzon létre duplikátumot. A helyi időhöz kötött feladatokat, például a reggeli kiküldéseket, időzóna szerint ütemezze. A napi riportot a helyi éjféltől a következő helyi éjfélig, UTC-re átszámítva számolja, és az óránkénti átlagot ne ossza el fixen 24-gyel.

7. Frissítse az időzóna-adatbázist, és tesztelje az átállási napokat

Az időzóna-adatok az operációs rendszeren, a programnyelv futtatókörnyezetén, a könyvtárakon és az adatbázison keresztül érkeznek, ezért frissítésüket tegye a rendszeres karbantartás részévé. Szabályváltozás után számolja újra a jövőbeli időpontok származtatott UTC-értékeit. Az automatizált teszteket futtassa rögzített dátumokra, például 2027. március 28-ra és október 31-re, valamint eltérő szerver- és böngészőoldali időzónával.

Az egyes megközelítések előnyei és hátrányai

  • Minden UTC-ben: egyszerű az időpillanatok összehasonlítása és rendezése, de az ismétlődő időpontok óraátállításkor elcsúsznak, a jövőbeli időpontok pedig az időzóna-szabályok változásakor is.
  • Minden a szerver helyi idejében: kényelmes egy országban működő cégnek, de az őszi éjszakán kétértelmű, és érzékeny arra, ha a szervert másik időzónába költöztetik.
  • Helyi idő, időzóna és származtatott UTC: időpontokhoz helyes, de több oszlopot, világos szabályokat és az időzóna-adatbázis frissítése utáni újraszámítást igényel.
  • Megjelenítés a felhasználó időzónájában: online megbeszéléseknél természetes, konkrét helyszínhez kötött szolgáltatásoknál zavaró, ott a helyszín időzónájának van értelme.

A legtöbb üzleti alkalmazáshoz kombinációt javaslunk: az időpillanatok UTC-ben, az időpontok helyi időben időzónával, a megjelenítés pedig a helyszín időzónájában, az időzóna egyértelmű feltüntetésével.

Gyakori hibák

  • Egyetlen UTC-időként tárolt ismétlődő időpont.
  • Fix +01:00 eltolás vagy a szerver időzónája az időzónanév helyett egy időpontnál.
  • Az a feltételezés, hogy egy nap mindig 24 órából áll, emlékeztetőknél, határidőknél és riportoknál.
  • Az idő formázása a böngészőben megadott időzóna nélkül.
  • Helyi idő szerint 2:00 és 3:00 közé ütemezett éjszakai feladatok.
  • Elavult időzóna-adatbázis a szerveren, a konténerben vagy az alkalmazásban.
  • Tesztek, amelyek csak egy időzónában és soha nem az óraátállítás napján futnak.

Ellenőrzőlista a specifikációhoz és az átvételhez

  • Minden időadatnak meghatározott típusa van: időpillanat, helyi időpont, ismétlődés, dátum vagy üzleti nap.
  • Az időpontoknál és a telephelyeknél tárolva van az IANA időzóna neve.
  • Az API UTC-eltolással küldi az időt, időpontoknál az időzóna nevét is.
  • A felület mutatja, melyik időzónában van megadva az idő.
  • A nem létező és a kétszer előforduló idő, valamint az ismétlődések kezelése dokumentált és tesztelt.
  • A riportok a cég időzónájában számolják az üzleti napot, és kezelik a 23 és a 25 órás napot is.
  • Az időzóna-adatbázis frissítése a karbantartás része, és utána a jövőbeli időpontokat újraszámolják.

Gyakori kérdések

Elég minden időt UTC-ben tárolni?

Időpillanatoknál igen, a helyi időben egyeztetett jövőbeli időpontoknál nem. Az RFC 9557 szerint egy elnevezett időzóna szabályai változhatnak, és az adat feldolgozásakor érvényes szabályok számítanak. Ezért a helyi időt időzónával tárolja, az UTC-t pedig ebből származtassa.

Foglalkoznunk kell ezzel, ha csak belföldi ügyfeleink vannak?

Igen. Az óraátállítás egyetlen időzónát is érint, a szerver, az adatbázis vagy az ügyfél telefonja pedig a cégétől eltérő időzónára lehet beállítva. A hibák ezért akár csak az átállás éjszakáján vagy az azt követő hetekben derülnek ki.

Mi legyen egy nem létező órára eső időponttal?

A foglalási űrlap ne kínálja fel. Ha ilyen időpont importból vagy ismétlődésből keletkezik, alkalmazza a rögzített szabályt, például az iCalendar szerinti eltolást 3:30-ra, és az érintett foglalásokat mutassa meg ellenőrzésre a diszpécsernek.

Milyen gyakran változik az időzóna-adatbázis?

Folyamatosan, amikor az államok módosítják az időzónák határait, az UTC-eltolást vagy a nyári időszámítás szabályait. Egy változás akár csak néhány nappal a hatálybalépés előtt is megjelenhet, ahogy a 2026f kiadás mutatta. Ezért a szokásos rendszerfrissítésekkel együtt frissítse, ne csak akkor, amikor probléma jelentkezik.

Ellenőriztetné az alkalmazása időkezelését?

Ha alkalmazása foglalásokkal, ütemezéssel, emlékeztetőkkel vagy napi riportokkal dolgozik, segítünk az időadatok felmérésében, az adatmodell átalakításában, az óraátállítási napok tesztelésében és a már tárolt időpontok javításában is. Munkánkról bővebben az egyedi webalkalmazások oldalon olvashat.

Küldjön nekünk rövid leírást arról, mely időpontok vagy riportok csúsznak el, és mikor történt. Az alkalmazások fejlesztéséről és üzemeltetéséről további cikkeket a blogunkon talál.

Források

Válassza ki, mely sütiket engedélyezi. Döntését bármikor módosíthatja a lábléc hivatkozásán vagy a sütik gombon keresztül.

Adatvédelem és a cookie-k részletei