Tahle chyba by zasloužila pochod hanby. Kdyby se autor tohoto *nedorozumění* zamyslel nad limity, asi by rychle přišel na to, že datum 2201010000 a každá minuta poté je větší než svatých 2147483647. Po pětisekundovém zamyšlení by přišel s tím, že když už opravdu musí převádět* řetězec na integer, mohll by aspoň záznam data začínal měsícem a ne dvojčíslím roku a měl by řádně zkontrolovat vstup. Ani to ale neodpovídá na otázku "Proč?"
Proč se tu vůbec používá takový úchylný formát data? Koho vůbec napadlo převádět číselný řetězec na integer?
* v chybě se píše "Can't convert "2201010001" to long" . Hádám, že jde o snahu ušetřit pár bitů nebo pár řádků kódu.
Po pětisekundovém zamyšlení by přišel s tím, že když už opravdu musí převádět* řetězec na integer, mohll by aspoň záznam data začínal měsícem a ne dvojčíslím roku
Po desetisekundovém zamyšlení by přišel na to, že s měsícem na začátku to nepude sortovat. Ale ani to ale neodpovídá na otázku "Proč?". :-D
Kdyby se autor zamyslel nad limity, tak se tato chyba nestala. Realisticky vzato se programátoři jen málokdy zamýšlejí nad limity datových typů a prográmátor této funkcionality nebude vyjímka.
Nad limitem datového typu by jste se měl zamyslet (a nejlépe i ošetřit) při každé operaci s proměnnou, včetně například operace +. A řekněme si upřímě, to nedělá nikdo. Mimochodem v některých jazycích (např C a C++) není chování overflow (nebo některých typů overflow) definováno, tím se (korektní) ošetření takové situace stává docela tricky.
Souhlas - jinak na tohle je paradoxně dobré začít potenciální programátory vzdělávat na Arduinu a podobných platformách. Jelikož má Arduino int jen 2B, náráží se na omezení rozsahem poměrně často a je docela zábava sledovat, jak nechápající student dostává "naprosto nesmyslná" čísla a marně přemýšlí, kde udělal chybu, protože opravdu musí svému kódu rozumět a nemůže se spoléhat na debugger, výjimky apod...
Zrovna nedávno jsem zadával úlohu na kreslení kurzoru (křížku) na malém oled displeji podle naklonění joysticku. Analogový vstup je 10bitový, displej má šířku 128 px, takže klasická trojčlenka na přepočet výchylky na pixely analogRead(A0)*127/1023 dává parádně nesmyslné výsledky, pokud se nepřetypuje aspoň jeden argument na long :-).
A nebo na nejakem plne 32 bitovem processoru - treba Texas DSP TMS320C3x:
sizeof(char) = sizeof(short) = sizeof(int) = sizeof(long) = 1, ale to 1 je 32 bitu :-)
Takze clovek si pak do char ulozi 16milionu, a kupodivu to pak i nazpet precte!
To pak cloveka rychle prejdou takove manyry jako pretypovavat char[] na int * .....
4. 1. 2022, 10:24 editováno autorem komentáře
Jenže tohle je docela běžně používaný formát: YYMMDDHHMM.
Výhoda je v tom, že se podle něj dá řadit a je snadné a rychlé z něj vytáhnout jednotlivé části i bez znalosti přestupných roků a podobných věcí. Při použití UNIX time sice řazení funguje také, ale pro filtrování se člověk neobejde bez použití knihoven. A i zdánlivě triviální operace jako "který to byl měsíc" je ve skutečnosti výpočet na docela dlouho. Rozhodně ne pár řádků kódu, spíše pár stovek. Zkuste si třebas napsat vlastnoručně jak z UNIX time získat informaci, zda jde o datum v květnu (pátém měsíci).
Pokud potřebujete řadit a filtrovat obrovské množství dat na podmínky typu "rok 2021" nebo "květen", pak použijete právě něco jako je YYYYMMDDHHMMSS.
I když, popravdě jsem se už dlouho nesetkal s verzí YY, žil jsem v domění, že pár desítek let se používá jen YYYY.
PS: Víte, že MS Office má zabugované ukládání datumu jako čísla? V jejich verzi je rok 1900 přestupný a tudíž existuje datum 29.2.1900. A to by si člověk myslel, že na "počet dnů od 1.1.1900, včetně" nejde nic pokazit :-)
A to unix time ještě neumí vyjádřit libovolný čas a naopak mohou v budoucnosti existovat hodnoty, které budou neplatný unix time – protože unix time nepočítá s přestupnými sekundami. Takže pro vážnou práci s časem je to vlastně dost nevhodná reprezentace.
U toho přestupného roku 1900 v Excelu je to ještě zajímavější – ta chyba je v Excelu záměrně, kvůli kompatibilitě s Lotus 1-2-3.
> i zdánlivě triviální operace jako "který to byl měsíc" je ve skutečnosti výpočet na docela dlouho. Rozhodně ne pár řádků kódu, spíše pár stovek.
Triviální operace to není, ale stovky řádků snad nezabere...
Unix time je naprosto triviální, protože nemá přestupné sekundy.
A přestupné roky lze řešit tak, že se počítá v 400letých cyklech a celý timestamp se posune tak, aby první den v "roce" byl 1. březen (pak vychází poslední den v přestupném "roce" na 29. únor). Je to trik použitý v mnoha knihovnách a je to naprosto triviální naprogramovat (celá dekompozice je pak na pár řádků a je i úžasně rychlá, protože i když je timestamp 64-bit, tak ten 400letý cyklus se vleze do 32-bit).
Plně souhlasím. Navíc není větší frustrace než když vám pár hodin po novém roce začnou volat klienti, že se jim zřejmě nabořil Exchange a že něco neběží jak má. Google v té době také ještě nic neznal. Naštěstí to brečelo do logu ohledně convert to long ,tak, že mne napadlo antimalware filtr vypnout a mailflow se obnovil. Bylo třeba to vypnout na všech 2016 a 2019 Exchange, tedy tento problém někdo zanesl do Exchange ne zas tak dávno. Skvělý dárek k novému roku od MS. Už se těším na prohlášení od Microsoftu že na Exchange online tento problém potají již opravili a že je to důvod k migraci k nim. :)