W niektórych systemach wartość czasu 9999-12-31 jest używana jako „koniec czasu” jako koniec czasu, który komputer może obliczyć. Ale co jeśli się zmieni? Czy nie lepiej byłoby zdefiniować ten czas jako zmienną wbudowaną?
W C i innych językach programowania zwykle istnieje zmienna taka MAX_INT
lub podobna, aby uzyskać największą wartość, jaką może mieć liczba całkowita. Dlaczego nie ma podobnej funkcji MAX_TIME
np. Ustawiania zmiennej na „koniec czasu”, który dla wielu systemów zwykle wynosi 9999-12-31. Czy w celu uniknięcia problemu zakodowania w niewłaściwym roku (9999) systemy te mogłyby wprowadzić zmienną „końca czasu”?
** Prawdziwy przykład **
End of validity date: 31/12/9999.
(oficjalne dokumenty są wymienione w ten sposób) Bloger chce napisać stronę, która jest zawsze na górze, stronę powitalną. Podano datę jak najdalej w przyszłości:
3000? Tak, strona powitalna, z którą się zmierzysz, została opublikowana 1 stycznia 3000 r. Więc ta strona będzie na zawsze utrzymywana na szczycie bloga =) Tak naprawdę jest opublikowana 31 sierpnia 2007 r.
Odpowiedzi:
Zastanów się, dlaczego potrzebujesz takiej zmiennej.
Najprawdopodobniej kłamiesz na temat swoich danych: ilekroć potrzebujesz zmiennej „koniec czasu”, nie masz na myśli faktycznego końca czasu; raczej wyrażasz takie rzeczy jak „nie ma górnej granicy dla tej daty”, „to wydarzenie trwa w nieskończoność” lub podobne.
Prawidłowym rozwiązaniem jest zatem wyrażenie tych zamiarów bezpośrednio zamiast polegania na magicznej wartości: użyj dopuszczalnych typów dat (gdzie
null
wskazuje „brak ustawionej daty końcowej”), dodaj „nieokreślone” pole boolowskie, użyj polimorficznego opakowania (które może może to być prawdziwa data lub specjalna „nieokreślona” wartość), lub cokolwiek, co oferuje Twój język programowania.Oczywiście prawidłowe rozwiązanie nie zawsze jest wykonalne, więc możesz w końcu użyć magicznej wartości, ale kiedy to zrobisz, musisz zdecydować o odpowiedniej wartości dla każdego przypadku, ponieważ które daty mają, a nie sens ma zależeć od modelowanej domeny - jeśli przechowujesz znaczniki czasu dziennika, 01/01/2999 to rozsądny „koniec czasu”; szanse, że Twoja aplikacja będzie nadal używana prawie za 1000 lat, są, jak sądzę, praktycznie zerowe. Podobne uwagi dotyczą aplikacji kalendarza. Ale co, jeśli twoje oprogramowanie ma obsługiwać dane naukowe, powiedzmy, długoterminowe prognozy dotyczące klimatu Ziemi? Ci mogą chcieć spojrzeć tysiąc lat w przyszłość. Lub posunąć się o krok dalej; astronomia, dziedzina, w której rozumowanie w bardzo dużych odstępach czasowych rzędu miliardów lat jest całkowicie normalne, zarówno na ścieżkę, jak i przyszłość. Dla tych osób 01/01/2999 to absolutnie absurdalne maksimum. OTOH, system kalendarza, który jest w stanie poradzić sobie z przedziałami czasowymi 10 bilionów lat w przyszłość, nie jest praktycznie praktyczny dla systemu śledzenia wizyt u dentysty, choćby ze względu na pojemność.
Innymi słowy, nie ma jednego najlepszego wyboru dla wartości, która jest zła i arbitralna z definicji na początek. Dlatego tak rzadko zdarza się, aby zdefiniować go w dowolnym języku programowania; te, które zwykle nie nazywają go „końcem czasu”, ale raczej czymś takim
DATE_MAX
(lubDate.MAX
), i rozumieją to jako „największą wartość, którą można zapisać w typie danych daty”, a nie „koniec czasu” lub "w sposób nieokreślony".źródło
null
w tym przypadku nie jest używany jako wartość specjalna, jest używany jako poprawne znaczenienull
, którego „brakuje”. Więc jeśli twoje pole jestExpiryDate
, co jest bardziej poprawne:null
(co oznacza brak daty ważności) lubEND_OF_TIME
(które, o ile wiemy, nie istnieje). Oczywiście,null
czyNoValue
coś podobnego jest lepszym rozwiązaniem.Jako przemysł byliśmy bardzo krótkowzroczni i arbitralni w dążeniu do zaoszczędzenia kilku bajtów, np.
31 grudnia 99IMHO najlepiej postawić na utrzymanie odpowiedniego poziomu abstrakcji w „maksymalnym terminie” i mieć nadzieję, że wspólne rozwiązanie rozwiązało ten problem, zanim nadejdzie czas.
np. w .NET, DateTime.MaxValue jest arbitralnie
23:59:59.9999999, December 31, 9999, exactly one 100-nanosecond tick before 00:00:00, January 1, 10000
. Więc jeśli moje założenia dotyczące mojej długowieczności są fałszywe, a nadejdzie rok 10000, mam raczej nadzieję, że rekompilacja mojej aplikacji z późniejszą wersją frameworka rozszerzy sięDateTime.MaxValue
(np. Poprzez zmianę typu podstawowego) na nową dowolną wartość i wykop ten problem jeszcze przez kilka tysiącleci.Edytować
(Wzmacniając uwagę tdammerów, że zamiast fałszować sztuczną datę, bardziej poprawne jest wyraźne podkreślenie konsumentowi faktu, że nie mamy daty końcowej).
Jako alternatywa dla używania
null
, która ma negatywną konsekwencję zgodności typu z dowolnym typem odniesienia (w tym .Net Nullable`), co prawdopodobnie spowoduje problemy z NRE u konsumentów, którzy zapomną sprawdzić, w językach FP, powszechnym jest używanie Opcja lub może Wpisz opakowanie wokół wartości, która może zostać zwrócona lub nie.Pseudo kod:
Zaletą tego jest to, że zmusza konsumenta do uzasadnienia w obu przypadkach. Dopasowywanie wzorców jest również powszechne tutaj:
źródło
NaT
wartości „ ” itp.Prawdopodobnie chcesz mieć
algebraic data type
wariant z nieskończonym dużymdate
. Następnie zdefiniuj porównanie, w któryminfinite
wariant będzie zawsze większy niż jakikolwiek innydate
.Przykład w Scali:
http://ideone.com/K5Kuk
źródło
Przechowuj swoje czasy w postaci 64-bitowej liczby zmiennoprzecinkowej podwójnej precyzji IEE754 i możesz jej użyć
+INF
. Nie używaj pojedynczej precyzji, która jest dokładna tylko do 7 cyfr, co jest nieco niskim wynikiem dla daty.źródło
Cocoa / Objective-C ma fabryczne metody [NSDate distantPast] i [NSDate distantFuture], które reprezentują dokładnie to, o czym mówisz.
Wartości zwrócone przez bieżącą implementację są stałymi reprezentującymi około 0 AD i 4000 AD, chociaż nie są one gwarantowane ani udokumentowane.
źródło
Na ogół nie ma takiej wartości, ponieważ nie byłaby przydatna jako konstrukcja języka.
MAX_INT
i to wszystko ma jakiś cel. Można ich użyć w kodzie, aby sprawdzić, czy nie występują przepełnienia. Jest to przydatne, jeśli zamierzasz tworzyć duże obiekty danych i zarządzać nimi w tablicach, wektorach i innych obiektach. Jest to również wartość specyficzna dla platformy.Przypadek użycia
MAX_DATE
wartości jest trudniejszy do zauważenia. Zazwyczaj są to tylko wartości, nie są one używane jako część struktury programu, a więc krążenie wokół wartości nie miałoby katastrofalnych konsekwencji dla programu (choć może to mieć wpływ na dane). Ponadto typy dat i godzin w C, C ++ itp. Są zwykle bardziej ściśle określone; więc osoby piszące program nie muszą się martwić, że może się zmieniać między platformami.źródło
W jednym z wykonanych przez nas projektów mieliśmy sytuację, w której wielkość bazy danych została przeprowadzona w sposób, który nie byłby możliwy do utrzymania po 30 latach korzystania z oprogramowania. Kiedy klient zapytał wówczas naszego głównego inżyniera: „No cóż, co zrobimy po 30 latach używania twojego oprogramowania?” Nasz główny inżynier, chłodny jak ogórek, odpowiedział wzruszeniem ramion: „Pójdziemy na piwo!”
Chodzi o to, aby po prostu użyć daty, która jest wystarczająco daleko w przyszłości. Możliwe, że twoje oprogramowanie zostanie do tego czasu zaktualizowane lub wymienione. :)
źródło