Muszę porównać dwa Date
s (np. date1
I date2
) i wymyślić, boolean sameDay
co jest prawdą o dwóch Date
sach tego samego dnia, i fałszywe, jeśli nie są.
W jaki sposób mogę to zrobić? Wydaje się, że panuje tutaj zamieszanie ... i chciałbym unikać wciągania innych zależności poza JDK, jeśli to w ogóle możliwe.
wyjaśnić: jeśli date1
i date2
dzielić ten sam rok, miesiąc i dzień, wówczas sameDay
jest to prawda, w przeciwnym razie jest to fałsz. Zdaję sobie sprawę, że wymaga to wiedzy o strefie czasowej ... byłoby miło przejść w strefie czasowej, ale mogę żyć z czasem GMT lub czasem lokalnym, o ile wiem, jakie jest zachowanie.
ponownie, aby wyjaśnić:
date1 = 2008 Jun 03 12:56:03
date2 = 2008 Jun 03 12:59:44
=> sameDate = true
date1 = 2009 Jun 03 12:56:03
date2 = 2008 Jun 03 12:59:44
=> sameDate = false
date1 = 2008 Aug 03 12:00:00
date2 = 2008 Jun 03 12:00:00
=> sameDate = false
Odpowiedzi:
Pamiętaj, że „ten sam dzień” nie jest tak prostym pojęciem, jak się wydaje, gdy można zaangażować różne strefy czasowe. Powyższy kod dla obu dat oblicza dzień w zależności od strefy czasowej używanej przez komputer, na którym działa. Jeśli nie jest to potrzebne, musisz przekazać odpowiednie strefy czasowe do
Calendar.getInstance()
połączeń, po tym, jak zdecydujesz, co dokładnie masz na myśli, mówiąc „tego samego dnia”.I tak, Joda Time
LocalDate
sprawiłoby, że całość byłaby o wiele czystsza i łatwiejsza (chociaż występowałyby te same trudności dotyczące stref czasowych).źródło
Co powiesz na:
W razie potrzeby możesz także ustawić strefę czasową na SimpleDateFormat.
źródło
SimpleDateFormat
metoda jest w rzeczywistości szybsza niż druga wspomniana tutaj za pomocąCalendar
s.Calendar
Metoda ta zajmuje średnio połowę czasu . (Przynajmniej w moim systemie). Sława!Używam do tego pakietu „apache commons lang” (mianowicie org.apache.commons.lang.time.DateUtils )
źródło
Możesz uniknąć zewnętrznych zależności i pogorszenia wydajności korzystania z Kalendarza, obliczając liczbę dni Juliana dla każdej z dat, a następnie porównując te:
źródło
Date
nie zawierają pojęcia stref czasowych, więc nie ma sposobu, aby to arbitralnie naprawić.Joda-Time
Jeśli chodzi o dodawanie zależności, obawiam się, że java.util.Date & .Calendar są tak złe, że pierwszą rzeczą, którą robię w każdym nowym projekcie, jest dodanie biblioteki Joda-Time. W Javie 8 możesz użyć nowego pakietu java.time, zainspirowanego Joda-Time.
Rdzeniem Joda-Time jest
DateTime
klasa. W przeciwieństwie do java.util.Date, rozumie przypisaną strefę czasową (DateTimeZone
). Podczas konwersji z juDate przypisz strefę.LocalDate
Jednym ze sposobów sprawdzenia, czy dwie daty wylądują w tym samym dniu, jest konwersja na
LocalDate
obiekty.Ta konwersja zależy od przypisanej strefy czasowej. Aby porównać
LocalDate
obiekty, muszą zostać przekonwertowane na tę samą strefę.Oto mała metoda użyteczności.
Lepszym rozwiązaniem byłby kolejny argument, określający strefę czasową zamiast zakładania, że należy użyć strefy czasowej pierwszego obiektu DateTime.
Reprezentacja łańcucha
Innym podejściem jest utworzenie ciągu reprezentującego część daty dla każdej daty i godziny, a następnie porównanie ciągów.
Ponownie, przypisana strefa czasowa ma kluczowe znaczenie.
Przedział czasu
Uogólnione rozwiązanie polega na zdefiniowaniu przedziału czasu, a następnie zapytaniu, czy przedział zawiera cel. Ten przykładowy kod znajduje się w Joda-Time 2.4. Zauważ, że klasy związane z „północą” są przestarzałe. Zamiast tego użyj
withTimeAtStartOfDay
metody. Joda-Time oferuje trzy klasy reprezentujące przedział czasu na różne sposoby: Interwał, Okres i Czas trwania.Stosując podejście „półotwarte”, w którym początek zakresu jest włączający, a zakończenie wyłączny.
Strefa czasowa celu może być inna niż strefa czasowa przedziału.
java.time
Java 8 i nowsze wersje są dostarczane ze środowiskiem java.time . Zainspirowany przez Joda-Time, zdefiniowany przez JSR 310 i rozszerzony przez projekt ThreeTen-Extra. Zobacz samouczek .
Twórcy Joda-Time poinstruowali nas wszystkich, abyśmy jak najszybciej przenieśli się na java.time. W międzyczasie Joda-Time kontynuuje działalność jako aktywny projekt. Ale oczekuj, że przyszłe prace pojawią się tylko w java.time i ThreeTen-Extra, a nie w Joda-Time.
Podsumowując java.time w pigułce…
Instant
To moment na osi czasu w UTC. Zastosuj strefę czasową (ZoneId
), aby uzyskaćZonedDateTime
obiekt. Aby przenieść się na osi czasu, aby uzyskać mgliste pojęcie o nieokreśloną datę czasie, korzystać z „lokalnych” klas:LocalDateTime
,LocalDate
,LocalTime
.Logika omówiona w części Joda-Time tej odpowiedzi dotyczy java.time.
Stara klasa java.util.Date ma nową
toInstant
metodę konwersji na java.time.Określenie daty wymaga strefy czasowej.
Stosujemy ten obiekt strefy czasowej w
Instant
celu uzyskaniaZonedDateTime
. Z tego wyodrębniamy wartość tylko daty (aLocalDate
), ponieważ naszym celem jest porównywanie dat (nie godzin, minut itp.).Zrób to samo z drugim
java.util.Date
obiektem, którego potrzebujemy do porównania. Zamiast tego wykorzystam bieżący moment.Użyj specjalnej
isEqual
metody, aby przetestować tę samą wartość daty.źródło
LocalDate localDate = LocalDate.fromDateFields(yourJavaUtilDate);
fromDateFields()
w mojejLocalDate
klasie .Konwertuj daty na Java 8 java.time.LocalDate, jak pokazano tutaj .
źródło
ZoneId.of("America/Phoenix")
lubZoneId.of("Europe/Budapest")
zamiast domyślnych ustawień systemowych.Java 8
Jeśli używasz Java 8 w swoim projekcie i porównujesz
java.sql.Timestamp
, możesz użyćLocalDate
klasy:Jeśli używasz
java.util.Date
, spójrz na odpowiedź Istvan, która jest mniej dwuznaczna.źródło
date1
i takdate2
jestjava.sql.Timestamp
?Date
Zrozumiałbym, zgodnie z pytaniemjava.util.Date
. Również twój kod wykorzystuje ustawienia strefy czasowej komputera, co w wielu przypadkach będzie w porządku; nadal wolę wyrazić ten fakt w kodzie.java.sql.Timestamp
. Jak powiedziałeś, ogólnie lepiej jest wyraźnie ustawić strefę czasową.źródło
DLA UŻYTKOWNIKÓW ANDROIDA:
Możesz użyć,
DateUtils.isToday(dateMilliseconds)
aby sprawdzić, czy podana data jest aktualna, czy nie.Dokumentacja interfejsu API: https://developer.android.com/reference/android/text/format/DateUtils.html#isToday(long)
źródło
DateUtils.isToday(x.getTime())
(x to instancja java.util.date) zrobioprócz rozwiązania Binil Thomas
stosowanie
źródło
Dla twórców Kotlin jest to wersja z porównywaniem sformatowanych ciągów znaków:
To nie jest najlepszy sposób, ale jest krótki i działa.
źródło
SimpleDateFormat
Klasa została wyparta lat temu przez nowoczesnejava.time.DateTimeFormatter
klasy zdefiniowanej w JSR 310. Sugerowanie jego wykorzystania w 2019 jest słaba rada.możesz zastosować tę samą logikę, co rozwiązanie SimpleDateFormat, nie polegając na SimpleDateFormat
źródło