Bardzo często spotykam się z negatywnymi opiniami na temat Javy Date
i innych zajęć związanych z datą. Będąc programistą .NET nie mogę w pełni (bez korzystania z nich) zrozumieć, co jest z nimi nie tak.
Czy ktoś może rzucić na to trochę światła?
Bardzo często spotykam się z negatywnymi opiniami na temat Javy Date
i innych zajęć związanych z datą. Będąc programistą .NET nie mogę w pełni (bez korzystania z nich) zrozumieć, co jest z nimi nie tak.
Czy ktoś może rzucić na to trochę światła?
Odpowiedzi:
Ach, Date
klasa Java . Być może jeden z najlepszych przykładów tego, jak nie robić czegoś w żadnym języku i nigdzie. Gdzie mam zacząć?
Przeczytanie JavaDoc może skłonić nas do pomysłu, że programiści mają naprawdę dobre pomysły. Mówi o różnicy między UTC i GMT , pomimo faktu, że różnica między nimi to w zasadzie sekundy przestępne (co zdarza się dość rzadko ).
Jednak decyzje projektowe naprawdę marnują wszelkie myśli o byciu dobrze zaprojektowanym API. Oto niektóre z ulubionych błędów:
null
. W rezultacie mamy 0..11 (dziś jest to 11 miesiąc 109 roku). Istnieje podobna liczba ++ i - w miesiącach w celu konwersji na ciąg.Calendar
, Przeznaczony do „fix” to rzeczywiście czyni te same błędy. Nadal są zmienne.Date
reprezentuje a DateTime
, ale aby odnieść się do tych w krainie SQL, istnieje inna podklasa java.sql.Date
, która reprezentuje jeden dzień (choć bez skojarzonej z nim strefy czasowej).TimeZone
s skojarzonych z a Date
, więc zakresy (takie jak „cały dzień”) są często przedstawiane jako północ i północ (często w dowolnej strefie czasowej)Na koniec warto zauważyć, że sekundy przestępne generalnie korygują się względem dobrego zegara systemowego, który jest aktualizowany za pomocą ntp w ciągu godziny (patrz linki poniżej). Prawdopodobieństwo, że system będzie nadal działał po wprowadzeniu dwóch sekund przestępnych (minimum co sześć miesięcy, praktycznie co kilka lat) jest raczej mało prawdopodobne, zwłaszcza biorąc pod uwagę fakt, że od czasu do czasu trzeba ponownie wdrażać nowe wersje kodu . Nawet użycie dynamicznego języka, który regeneruje klasy lub coś takiego jak silnik WAR, zanieczyszcza przestrzeń klas i ostatecznie zabraknie permgen.
JSR 310 , który zastąpił stare klasy daty i godziny java.time w Javie 8, uzasadnia się w oryginalnym JSR następująco:
2.5 Jakie potrzeby społeczności Java zostanie uwzględnione w proponowanej specyfikacji?
Obecnie Java SE ma dwa oddzielne interfejsy API daty i czasu - java.util.Date i java.util.Calendar. Oba interfejsy API są konsekwentnie opisywane jako trudne w użyciu przez programistów Java na blogach i forach. Warto zauważyć, że oba używają indeksu zerowego przez miesiące, co jest przyczyną wielu błędów. Przez lata kalendarz cierpiał z powodu wielu błędów i problemów z wydajnością, głównie z powodu wewnętrznego przechowywania jego stanu na dwa różne sposoby.
Jeden klasyczny błąd (4639407) uniemożliwił utworzenie pewnych dat w obiekcie kalendarza. Można napisać sekwencję kodu, która mogłaby utworzyć datę w niektórych latach, ale nie w innych, uniemożliwiając niektórym użytkownikom wprowadzenie prawidłowych dat urodzenia. Było to spowodowane tym, że klasa Calendar zezwalała na uzyskanie czasu letniego tylko o jedną godzinę, podczas gdy historycznie było to plus 2 godziny w okresie drugiej wojny światowej. Chociaż ten błąd został już naprawiony, jeśli w jakimś momencie w przyszłości jakiś kraj zdecyduje się na wprowadzenie oszczędności czasu letniego o dodatkowe trzy godziny, to klasa kalendarza ponownie zostanie zerwana.
Obecny interfejs API Java SE również cierpi w środowiskach wielowątkowych. Wiadomo, że niezmienne klasy są z natury bezpieczne dla wątków, ponieważ ich stan nie może się zmienić. Jednak zarówno data, jak i kalendarz są zmienne, co wymaga od programistów jawnego rozważenia klonowania i wątków. Ponadto brak bezpieczeństwa wątków w DateTimeFormat nie jest powszechnie znany i był przyczyną wielu trudnych do wyśledzenia problemów z wątkami.
Oprócz problemów z klasami, które Java SE ma dla daty i godziny, nie ma klas do modelowania innych koncepcji. Daty lub godziny spoza strefy czasowej, czasy trwania, okresy i interwały nie mają reprezentacji klas w języku Java SE. W rezultacie programiści często używają int do reprezentowania czasu, a javadoc określa jednostkę.
Brak kompleksowego modelu daty i czasu powoduje również, że wiele typowych operacji jest trudniejszych niż powinny. Na przykład obliczenie liczby dni między dwiema datami jest obecnie szczególnie trudnym problemem.
Ten JSR zajmie się problemem pełnego modelu daty i czasu, w tym dat i godzin (ze strefami czasowymi i bez), czasów trwania i okresów, interwałów, formatowania i analizowania.
getMonth()
zera, od getYear()
1900 (tj. Rok 2009 jest reprezentowany jako 109).Date
klasy.Współczuję Ci ... jako były programista .NET zadawałem te same pytania, API czasowe w .NET (przedziały czasowe, przeciążenie operatorów) jest bardzo wygodne.
Po pierwsze, aby utworzyć konkretną datę, użyj przestarzałego interfejsu API lub:
Calendar c = Calendar.getInstance();
c.set(2000, 31, 12)
Aby odjąć dzień, w którym robisz złe rzeczy, takie jak
Date firstDate = ...
Calendar c = Calendar.getInstance();
c.setTime(fistDate);
c.add(Calendar.DATE,-1);
Date dayAgo = c.getTime();
albo gorzej
Date d = new Date();
Date d2 = new Date(d.getTime() - 1000*60*60*24);
Aby dowiedzieć się, ile czasu minęło między dwiema datami (w dniach / tygodniach / miesiącach) ... jest jeszcze gorzej
Jednak DateUtils z apache ( org.apache.commons.lang.time.DateUtils
) oferują kilka wygodnych metod i ostatnio odkryłem, że używam tylko ich
Jak napisał Brabster, Joda Time jest również dobrą biblioteką zewnętrzną, ale apache wydaje się bardziej „powszechny” niż cokolwiek innego ...
Period
i Duration
klas do obliczania i reprezentowania czasu, który upłynął, odpowiednio w skali lat-miesięcy-dni i godzin-minut-sekund.
Uważam, że API Date w Javie jest użyteczne, szczerze mówiąc. Większość zagadnień widziałem i słyszałem o odnoszą się do gadatliwości, konieczność zaangażowania wielu klas, aby zrobić coś pożytecznego ( Calendar
, Date
, DateFormat
/ SimpleDateFormat
) oraz brak prostych akcesorów jak getDayOfWeek()
.
Joda Time to szanowany alternatywny interfejs API w Javie, aw sekcji Why Joda Time podaje kilka argumentów wyjaśniających, dlaczego jest to realna alternatywa, która może być interesująca.