W moim kodzie muszę znaleźć wszystkie moje rzeczy, które wydarzyły się dzisiaj. Muszę więc porównać z datami od dzisiaj o 00:00 (północ wcześnie rano) do 12:00 wieczorem (północ dziś wieczorem).
Wiem ...
Date today = new Date();
... zabiera mnie teraz. I ...
Date beginning = new Date(0);
... daje mi zero czasu 1 stycznia 1970 roku. Ale jaki jest łatwy sposób, aby uzyskać zero czasu dzisiaj i zero czasu jutro?
AKTUALIZACJA; Zrobiłem to, ale na pewno jest łatwiejszy sposób?
Calendar calStart = new GregorianCalendar();
calStart.setTime(new Date());
calStart.set(Calendar.HOUR_OF_DAY, 0);
calStart.set(Calendar.MINUTE, 0);
calStart.set(Calendar.SECOND, 0);
calStart.set(Calendar.MILLISECOND, 0);
Date midnightYesterday = calStart.getTime();
Calendar calEnd = new GregorianCalendar();
calEnd.setTime(new Date());
calEnd.set(Calendar.DAY_OF_YEAR, calEnd.get(Calendar.DAY_OF_YEAR)+1);
calEnd.set(Calendar.HOUR_OF_DAY, 0);
calEnd.set(Calendar.MINUTE, 0);
calEnd.set(Calendar.SECOND, 0);
calEnd.set(Calendar.MILLISECOND, 0);
Date midnightTonight = calEnd.getTime();
java.util.Date
,java.util.Calendar
ijava.text.SimpleDateFormat
są teraz spuścizną , wyparte przez klasy java.time wbudowane w Javę 8 i nowsze wersje . Zobacz samouczek Oracle .Odpowiedzi:
java.util.Calendar
JDK 8 - java.time.LocalTime i java.time.LocalDate
Joda-Time
Jeśli używasz JDK <8, polecam Joda Time , ponieważ interfejs API jest naprawdę ładny:
Ponieważ wersja 2.3 Joda Time
DateMidnight
jest przestarzała , użyj tego:Podaj strefę czasową, jeśli nie chcesz bieżącej domyślnej strefy czasowej JVM.
źródło
toDateMidnight
jest przestarzały. Zobacz tę odpowiedź, aby uzyskać szczegółowe informacje: stackoverflow.com/a/19048833/363573ZonedDateTime
), tak jak w sekcji Joda-Time. TeLocal…
typy mają żadnych informacji o strefie czasowej - to jest cała ich celem nie stracić / ignore wszystkie offsetowe i strefa czasowa szczegóły. Zwłaszcza, że Pytanie mówi o wykorzystaniu tych wartości do porównania (może zapytań do bazy danych?), Strefowa wartość daty i godziny może być bardziej przydatna.Dla kompletności, jeśli używasz Java 8 , możesz również użyć
truncatedTo
metodyInstant
klasy, aby uzyskać północ w UTC .Jak napisano w Javadoc
Mam nadzieję, że to pomoże.
źródło
Date.from(date.toInstant().atZone(ZoneId.systemDefault()).truncatedTo(ChronoUnit.DAYS).toInstant())
truncatedTo
iatStartOfDay
.Najłatwiejszy sposób na znalezienie północy:
Następny dzień:
źródło
Pamiętaj,
Date
nie jest używany do reprezentowania dat (!). Aby przedstawić datę, potrzebujesz kalendarza. To:utworzy
Calendar
instancję reprezentującą aktualną datę w bieżącej strefie czasowej. Teraz musisz obciąć każde pole poniżej dnia (godzinę, minutę, sekundę i milisekundę), ustawiając je na0
. Masz dziś północ.Teraz, aby uzyskać północ następnego dnia, musisz dodać jeden dzień:
Pamiętaj, że dodanie
86400
sekund lub 24 godzin jest nieprawidłowe ze względu na czas letni, który może wystąpić w międzyczasie.AKTUALIZACJA: Jednak moim ulubionym sposobem radzenia sobie z tym problemem jest użycie klasy DateUtils z Commons Lang :
To używa
Calendar
za kulisami ...źródło
te metody pomogą ci-
i
źródło
Począwszy od JodaTime 2.3,
toDateMidnight()
jest przestarzały.Z aktualizacji z 2.2 na 2.3
Oto przykładowy kod bez
toDateMidnight()
metody.Kod
Dane wyjściowe ( mogą się różnić w zależności od lokalnej strefy czasowej )
źródło
DateTimeZone
instancji do tegoDateTime
konstruktora, aby podkreślić znaczenie określenia strefy czasowej, a nie przypadkowo, w zależności od wartości domyślnej:DateTimeZone timeZone = DateTimeZone.forID( "Europe/Paris" );
Inne odpowiedzi są poprawne, zwłaszcza odpowiedź java.time autorstwa arganzheng . Jak niektórzy wspomnieli, powinieneś unikać starych klas java.util.Date/.Calendar, ponieważ są one źle zaprojektowane, mylące i kłopotliwe. Zostały one wyparte przez klasy java.time.
Pozwól, że dodam uwagi na temat strategii związanej z obsługą północy i przedziałów czasu .
Wpół otwarty
W pracy z datą przedziały czasu są często określane przy użyciu metody „półotwartej”. W tym podejściu początek jest włączający, a zakończenie wyłączny . To rozwiązuje problemy, a jeśli jest konsekwentnie stosowane, znacznie ułatwia rozumowanie na temat obsługi daty i czasu.
Jednym z rozwiązanych problemów jest określenie końca dnia. Czy ostatnia chwila dnia
23:59:59.999
( milisekundy )? Być może w klasie java.util.Date (od najwcześniejszej Javy; kłopotliwe - unikaj tej klasy!) Oraz w bardzo udanej bibliotece Joda-Time . Ale w innym oprogramowaniu, takim jak baza danych, taka jak Postgres, ostatnia chwila będzie23:59:59.999999
( mikrosekund ). Ale w innym oprogramowaniu, takim jak framework java.time (wbudowany w Javę 8 i później, następca Joda-Time) oraz w niektórych bazach danych, takich jak Baza danych H2 , ostatnia chwila może być23:59.59.999999999
( nanosekundowa ). Zamiast dzielić włosy, myśl tylko w pierwszej chwili, a nie w ostatniej chwili.W Half-Open dzień rozpoczyna się od pierwszej chwili jednego dnia i idzie w górę, ale nie obejmuje pierwszej chwili następnego dnia. Zamiast myśleć w ten sposób:
… Pomyśl tak…
W pracy bazy danych, podejście to znaczy nie za pomocą
BETWEEN
operatora w SQL.Początek dnia
Co więcej, pierwsza chwila dnia nie zawsze jest porą dnia
00:00:00.0
. Czas letni (DST) w niektórych strefach czasowych i ewentualnie inne anomalie mogą oznaczać, że o innej porze zaczyna się dzień.Niech klasy java.time wykonają zadanie określające początek dnia za pomocą wywołania
LocalDate::atStartOfDay( ZoneId )
. Musimy więc objechaćLocalDate
i wrócić do,ZonedDateTime
jak widać w tym przykładowym kodzie.Zwróć uwagę na opcjonalne
ZoneId
. Jeśli zostanie pominięty, domyślna strefa czasowa JVM zostanie zastosowana domyślnie. Lepiej być wyraźnym.Strefa czasowa ma kluczowe znaczenie dla pracy z datą i godziną. Pytanie i niektóre inne odpowiedzi są potencjalnie wadliwe, ponieważ nie świadomie obsługują strefę czasową.
Konwertować
Jeśli musisz użyć java.util.Date lub .Calendar, poszukaj nowych metod konwersji dodanych do tych starych klas.
Przedział czasu
Nawiasem mówiąc, jeśli wykonujesz dużo pracy z upływem czasu, spójrz na:
Duration
Period
Interval
Interval
Klasa znajduje się w ThreeTen-Extra projektu przedłużenia do ram java.time. Ten projekt jest poligonem doświadczalnym dla ewentualnych przyszłych dodatków do java.time.Interval todayMontreal = Interval.of( todayStart.toInstant() , tomorrowStart.toInstant() );
O java.time
Środowisko java.time jest wbudowane w Javę 8 i nowsze wersje . Klasy te kłopotliwe zastąpić stary starszych klas Date-Time, takich jak
java.util.Date
,Calendar
, iSimpleDateFormat
.Projekt Joda-Time , teraz w trybie konserwacji , zaleca migrację do klas java.time .
Aby dowiedzieć się więcej, zobacz samouczek Oracle . I przeszukaj stos przepełnienia dla wielu przykładów i wyjaśnień. Specyfikacja to JSR 310 .
Możesz wymieniać obiekty java.time bezpośrednio ze swoją bazą danych. Użyj sterownika JDBC zgodnego z JDBC 4.2 lub nowszym. Nie potrzeba ciągów, nie ma potrzeby
java.sql.*
klas.Gdzie można uzyskać klasy java.time?
Projekt ThreeTen-Extra rozszerza java.time o dodatkowe klasy. Ten projekt jest poligonem doświadczalnym dla ewentualnych przyszłych dodatków do java.time. Można znaleźć kilka przydatnych klas tutaj takie jak
Interval
,YearWeek
,YearQuarter
, i więcej .źródło
java.time
Jeśli używasz języka Java 8 i nowszych, możesz wypróbować pakiet java.time ( samouczek ):
źródło
To wydaje się być opcją:
aby dodać do tego dzień
lub
Mam przeczucie, że to drugie jest preferowane w przypadku czegoś dziwnego, na przykład oszczędności w świetle dziennym, powodując, że dodanie 24 godzin nie wystarczy (patrz https://stackoverflow.com/a/4336131/32453 i inne odpowiedzi).
źródło
Zrobiłem to inaczej niż wszyscy tutaj. Jestem nowy w Javie, więc może moje rozwiązanie jest złe.
Nie jestem pewien, czy to działa, ale tak czy inaczej, byłbym wdzięczny za wszelkie opinie na temat tego rozwiązania.
Jestem zdezorientowany powyższym stwierdzeniem, że możesz obliczyć jutro, dzwoniąc:
Jeśli dodasz 1 do dnia miesiąca i jest to 31 dzień, czy nie dostaniesz 32 dnia miesiąca?
Dlaczego godziny / daty nie wszystkie są oparte na UTC w Javie? Sądzę, że strefy czasowe powinny być potrzebne tylko wtedy, gdy są używane z we / wy, ale wewnętrznie powinny być zawsze używane w UTC. Wydaje się jednak, że klasy zawierają informacje o strefie czasowej, która wydaje się nie tylko marnotrawiona, ale również podatna na błędy kodowania.
źródło
Apache Commons Lang
http://commons.apache.org/proper/commons-lang/javadocs/api-2.6/org/apache/commons/lang/time/DateUtils.html#isSameDay(java.util.Date , java.util.Date)
źródło
Najprostszy sposób z JodaTime
DateMidnight date = DateMidnight.now();
źródło
00:00:00.000
. Zamiast tego użyj nowejwithTimeAtStartOfDay
metody. Zaktualizuj do aktualnej wersji 2.4 Joda-Time i przeczytaj informacje o wersji. Przykład:DateTime today = DateTime.now( DateTimeZone.forID( "America/Montreal" ) ).withTimeAtStartOfDay();
Ponieważ jeden dzień to
24 * 60 * 60 * 1000
ms, północ tego dnia można obliczyć jako ...źródło
Prawie jak wcześniej, ale nikt nie wspomniał o parametrze AM_PM:
źródło
Calendar
klasa została zastąpiona wiele lat temu przez klasy java.timeZonedDateTime
.źródło
Date
klasa została wyparta przez lata temujava.time.Instant
. Unikaj korzystania wDate
dzisiejszych czasach.Używanie wspólnego apache ..
źródło
java.util.Date
,java.util.Calendar
ijava.text.SimpleDateFormat
są teraz spuścizną , wyparte przez klasy java.time wbudowane w Javę 8 i nowsze wersje . Zobacz samouczek Oracle .Wiem, że to bardzo stary post. Chciałem podzielić się tutaj swoją wiedzą!
W dniu dzisiejszym środkowa noc z dokładną strefą czasową możesz użyć następujących
Gdzie
(1000*60 * 330)
jest odejmowane, tj. Faktycznie związane ze strefą czasową, na przykład indyjska strefa czasowa, tj. Kalkuta różni się o 5: 30 godz. Od rzeczywistej. Odejmując to od konwersji na milisekundy.Więc zmień ostatnią odjętą liczbę według ciebie. Tworzę produkt, tj. Tylko z siedzibą w Indiach Więc użyłem określonego znacznika czasu.
źródło
Ale uwaga, że
java.sql.Date.toInstant()
zawsze rzucaUnsupportedOperationException
.Przez LocalDate do java.util.Date i odwrotnie, najprostsza konwersja?
źródło
Po staremu..
źródło
Date
.Date
klasa jest zawsze w UTC. Dlatego ignorujesz problem pożądanej / oczekiwanej strefy czasowej. Na przykład w Kolkata w Indiach zaczyna się nowy dzień wiele godzin wcześniej niż w UTC i kilka godzin później niż UTC w Montrealu Québec.