Excel do dziś udaje, że istnieje 29 lutego 1900 r., bo naprawienie błędu zepsułoby zgodność ze starymi arkuszami
Rok 1900 nie był przestępny, ale Excel traktuje go tak, jakby miał 29 lutego. Microsoft wyjaśnia, że zachowanie zostało odziedziczone dla zgodności z Lotus 1-2-3, który również używał takiego systemu dat. Błąd jest dziś dobrze znany i technicznie możliwy do poprawienia, lecz Microsoft świadomie go zachowuje: zmiana przesunęłaby ogromną liczbę historycznych numerów seryjnych dat i mogłaby zepsuć istniejące pliki oraz formuły. To jeden z najlepszych przykładów, gdy bug staje się częścią publicznego API.
1900 łamie prostą regułę „co cztery lata”
Rok przestępny występuje zwykle co cztery lata, ale lata podzielne przez 100 są wyjątkiem, chyba że dzielą się przez 400. Dlatego 1900 nie był przestępny, a 2000 był. Excel poprawnie obsługuje większość tej reguły, lecz specjalnie zachowuje wyjątek dla roku 1900.
Lotus 1-2-3 stworzył historyczne ograniczenie
Lotus był dominującym arkuszem kalkulacyjnym. Microsoft chciał, aby użytkownicy mogli przenosić pliki i formuły bez przesunięcia serial date values. Powielenie błędu było zatem decyzją kompatybilnościową, nie przypadkowym współczesnym defektem.
Serial 60 oznacza fikcyjny dzień
W klasycznym systemie dat Excela liczby reprezentują kolejne dni. Wartość odpowiadająca 29 lutego 1900 r. istnieje w sekwencji, mimo że data nie istniała. Wszystkie późniejsze daty muszą zachować to historyczne przesunięcie, aby stare arkusze nadal dawały te same wyniki.
Poprawienie błędu byłoby breaking change
Microsoft wymienia konsekwencje potencjalnej poprawki: przesunięcie dat o dzień i zmianę wyników funkcji takich jak WEEKDAY dla części zakresu. Liczba istniejących arkuszy sprawia, że koszt kompatybilności jest większy niż korzyść z matematycznej czystości.
Bug może stać się kontraktem
Jeżeli klienci tworzą dane zależne od określonego zachowania, nawet błąd zaczyna działać jak standard. Programista nowej implementacji kompatybilnego formatu musi czasem powtórzyć niepoprawne zachowanie, aby być naprawdę kompatybilnym.
Backward compatibility ma pamięć dłuższą niż firmy
Lotus 1-2-3 praktycznie zniknął z rynku, ale jego decyzja projektowa nadal żyje w Excelu. To niezwykły przykład technicznej genealogii: współczesny produkt może być ograniczony przez bug konkurenta sprzed wielu dekad. Takie historyczne zachowania powinny być też bardzo dobrze dokumentowane. Najgorszy jest bug kompatybilności, którego nikt już nie pamięta i który nowy zespół „naprawia”, nie wiedząc, że tysiące klientów zależą od starego wyniku.
Kompatybilność potrafi zamienić przypadkowy bug w permanentny standard
To zjawisko bywa nazywane bug compatibility. Jeśli konkurencyjny program, parser albo protokół ma zachowanie technicznie błędne, ale miliony dokumentów polegają właśnie na nim, nowa implementacja może być zmuszona je powtórzyć. Przeglądarki internetowe przez lata zachowywały wiele quirks starych stron z podobnego powodu. Emulatory procesorów, systemy plików i implementacje protokołów również czasem odtwarzają historyczne błędy, bo kompatybilność z istniejącymi danymi ma większą wartość niż elegancka specyfikacja. Excel 1900 jest wyjątkowo czytelnym przykładem: niepoprawna data została zakonserwowana jako część formatu i interfejsu. Im większy sukces produktu, tym droższe staje się późniejsze „naprawienie” pewnych decyzji. Dlatego publiczne formaty danych powinny być projektowane z większą ostrożnością niż wewnętrzna funkcja, którą można zmienić wraz z jednym release’em. Z punktu widzenia projektanta formatów danych wniosek jest brutalny: każde zachowanie, które zostanie zapisane w milionach dokumentów, może przestać być lokalnym szczegółem implementacji i stać się częścią kontraktu na dziesięciolecia. To również przestroga dla twórców API: użytkownicy mogą zacząć polegać nawet na zachowaniu nieopisanym w dokumentacji. Każda obserwowalna właściwość popularnego systemu ma szansę stać się de facto kontraktem.