Tech Life

Ilustrační obrázek

Kalendářové poklesky

10. 02. 2009 13:45    kategorie: Tech Life    autor: MKa    komentářů: 5

Gregoriánský kalendář se lidé učí používat odmalička a jsou na něj zvyklí, proto s ním obvykle nemají velké problémy. Pro programátory se však práce s datem snadno může stát noční můrou. Už dříve jste na blogu mohli vidět několik příkladů chyb, které při takové práci lze udělat. Dnes tu máme další takovou.
 
Představme si, že máme metodu, jejímž úkolem je určit počet dnů, které uplynuly mezi dvěma daty. Jako obvykle je možné postupovat několika způsoby, například prostým odečtením časových údajů nebo iterativním sečtením dnů za jednotlivé měsíce. Tyto dva příklady ilustruje následující poměrně dost upravený a zjednodušený kód z jednoho projektu. Máme zaručeno, že oba vstupní parametry obsahují půlnoc nějakého dne, tj. hodiny a minuty jsou vynulovány. Víme také, že koncové datum je vždy větší než počáteční (v reálu je na to test, který jsem pro přehlednost vynechal).

V ideálním případě by obě metody měly pro stejné parametry vracet vždy stejný výsledek. Je zde ale jedna chyba, která způsobuje, že tomu tak někdy být nemusí. Poznáte, za jakých okolností se projeví? A která metoda je v takovém případě ta chybná?

Poznámka: S hádankou to už přímo nesouvisí, ale pro doplnění kontextu uvádím, že ten příklad je opravdu dost upravený. Například ta iterace v druhé metodě není samoúčelná - kromě sčítání dnů se totiž v cyklu provádějí pro každý kousek měsíce i další výpočty, které pro nás ale nejsou nyní zajímavé.
Sdílet odkaz:
tisk

Diskuze k článku

MKa, 24.3.2009 15:59

Přesně tak, problém je opravdu v přechodu na letní čas, kdy má neděle pouze 23 hodin a tím pádem ji ta první metoda nezapočítá. Více detailů například na URL, které uvedl Marek.

Na závěr ještě poznámka na okraj k těm jednotkovým testům: Pozor na to, že rozhodně nejsou samospasitelné. Z principu vždy pokrývají pouze omezený prostor vstupních hodnot - a tak tomu bylo i zde. Nesouhlasím tedy s tím, že by se to s junit testem nestalo. Je poměrně velká šance, že zrovna takový vstup by se nepovedlo otestovat. A mimochodem, zrovna v tomto případě na příslušný výpočet test existoval. :)

Messa, 11.2.2009 14:55

První příklad je jednoduchý, funkční a elegantní, akorát se musí dát pozor, aby oba časy vyjadřovaly půlnoc ve stejné časové zóně (z toho plynou problémy okolo letního času). Na Unix timestamp je jinak pěkné, že je vždy v UTC a ignoruje přestupné sekundy.

Oba příklady si zaslouží vlastní (unit) test, pak by se ani v Et Neteře takové chyby nestávaly :-)

Marek, 10.2.2009 18:36

Chyba viz http://www.xmission.com/~goodhill/dates/deltaDates.html

Honza Martinek, 10.2.2009 17:21

Příklady jsem proběhl zlehka, ale že by letní čas? :-) S tím jsem měl x problémů, když jsem dělal nad databází, která nepracovala slušně s datem a počítal jsem to ručně, uáá, špatné vzpomínky.

Jiří Jakeš, 10.2.2009 17:21

Zdá se mi, že první případ nepočítá s přestupným rokem, čili pokud interval obsahuje i 29. únor, výsledky by se mohly lišit. Ale neověřoval jsem.

Jinak práce s datem/časem je samozřejmě tak snadná, jak kvalitní jsou nástroje. Já si oblíbil knihovnu Joda, která má operace s datem a časem zmáknuté opravdu skvělé. A mám za to, že se jí otvírají dvířka přímo do Java Core. Tak uvidíme…

Přidat příspěvek

 

Kontakt pro média


Máte zájem o další informace, odborný článek či přednášku na konferenci? Kontaktujte nás prosím na pr@etnetera.cz.

RSS - Tech life


RSS kanál Tech Life Blogu

Offlineblog

Offlineblog

Ljama


Komix z prostředí imaginární firmy.

ljama

Ještě jste ho nečetli? Tak tudy ...

 
Doporučujeme: Nabídka práce, volná pracovní místa - pracovní portál SPRÁVNÝKROK.CZ