Kontynuując pytanie programu Java dotyczące przepełnienia stosu , aby uzyskać bieżącą datę bez znacznika czasu :
Jaki jest najskuteczniejszy sposób na uzyskanie obiektu Date bez czasu? Czy jest jakiś inny sposób niż te dwa?
// Method 1
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
Date dateWithoutTime = sdf.parse(sdf.format(new Date()));
// Method 2
Calendar cal = Calendar.getInstance();
cal.set(Calendar.HOUR_OF_DAY, 0);
cal.set(Calendar.MINUTE, 0);
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MILLISECOND, 0);
dateWithoutTime = cal.getTime();
Aktualizacja :
Wiedziałem o Joda-Time ; Próbuję po prostu uniknąć dodatkowej biblioteki dla tak prostego (jak sądzę) zadania. Ale na podstawie dotychczasowych odpowiedzi Joda-Time wydaje się niezwykle popularny, więc mógłbym to rozważyć.
Mówiąc wydajnie , chcę uniknąć
String
tworzenia tymczasowych obiektów, z których korzystamethod 1
, tymczasemmethod 2
wydaje się, że to hack zamiast rozwiązania.
Odpowiedzi:
Czy jesteś absolutnie mają do użytku
java.util.Date
? Chciałbym dokładnie zaleca się użycie Joda czasu lubjava.time
pakiet z Java 8 zamiast. W szczególności, gdy Data i kalendarz zawsze stanowią szczególny moment w czasie, bez takiego pojęcia jak „tylko data” Joda czas ma mieć typ reprezentujący ten (LocalDate
). Twój kod będzie znacznie wyraźniejszy, jeśli będziesz w stanie używać typów reprezentujących to, co faktycznie próbujesz zrobić.Istnieje wiele, wiele innych powodów, aby używać Joda Time lub
java.time
zamiast wbudowanychjava.util
typów - są to na ogół znacznie lepsze interfejsy API. Wjava.util.Date
razie potrzeby zawsze możesz przekonwertować na / z granicy własnego kodu, np. W celu interakcji z bazą danych.źródło
Date
obiekt - ta odpowiedź formatuje datę na ciąg, co nie jest tym samym. Zasadniczo pytanie o datęDate
jest bezsensownym pytaniem bez dodatkowych informacji: strefy czasowej i używanego systemu kalendarza.Oto, co otrzymałem dzisiejszą datę z czasem ustawionym na
00:00:00
:źródło
Możesz użyć DateUtils.truncate z biblioteki Apache Commons.
Przykład:
źródło
Tak jest.
java.time
Java 8 i nowsze wersje są dostarczane z nowym wbudowanym pakietem java.time . Zobacz samouczek . Duża część funkcji java.time została przeniesiona z powrotem do Java 6 i 7 w ThreeTen-Backport, a następnie dostosowana do Androida w ThreeTenABP .
Podobnie jak Joda-Time , java.time oferuje
LocalDate
klasę reprezentującą wartość tylko daty bez pory dnia i strefy czasowej.Pamiętaj, że strefa czasowa ma kluczowe znaczenie dla ustalenia konkretnej daty. Na przykład o północy w Paryżu data w Montrealu wciąż jest „wczoraj”.
Domyślnie java.time używa standardu ISO 8601 do generowania ciągu reprezentującego wartość daty lub wartości daty i godziny. (Kolejne podobieństwo do Joda-Time.) Więc po prostu wywołaj,
toString()
aby wygenerować tekst podobny2015-05-21
.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 .
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
TimeZone.setDefault
czasie wykonywania i natychmiast wpływać na cały inny kod działający w tej JVM. Morał historii: Zawsze określaj strefę czasową.Najprostszy sposób:
źródło
long dateOnly = (currentTime / millisInDay) * millisInDay;
tym samym co pisanielong dateOnly = currentTime;
?Standardową odpowiedzią na te pytania jest użycie Joda Time . Interfejs API jest lepszy, a jeśli używasz formatatorów i parserów, możesz uniknąć nieintuicyjnego braku bezpieczeństwa wątków
SimpleDateFormat
.Korzystanie z Jody oznacza, że możesz po prostu:
Aktualizacja :: Korzystanie z java 8 można to osiągnąć za pomocą
źródło
LocalDate
klasę podobną do Joda-Time.DateTimeZone
do tego konstruktora LocalDate. Określenie bieżącej daty zależy od strefy czasowej, ponieważ Paryż rozpoczyna nową datę wcześniej niż Montréal. Pominięcie strefy czasowej powoduje zastosowanie domyślnej strefy czasowej maszyny JVM. Zwykle lepiej jest określać niż polegać na domyślnych.Jest to prosty sposób:
źródło
Nie ma sensu mówić o dacie bez znacznika czasu w odniesieniu do procedur Date w standardowym środowisku wykonawczym Java, ponieważ zasadniczo odwzorowuje ona konkretną milisekundę, a nie datę. Wspomniana milisekunda jest z natury związana z porą dnia, co czyni ją podatną na problemy strefy czasowej, takie jak czas letni i inne zmiany kalendarza. Zobacz, dlaczego odejmowanie tych dwóch razy (w 1927 r.) Daje dziwny wynik? na ciekawy przykład.
Jeśli chcesz pracować z datami zamiast milisekund, musisz użyć czegoś innego. W Javie 8 istnieje nowy zestaw metod zapewniających dokładnie to, o co prosisz. W przypadku języka Java 7 i wcześniejszych należy użyć http://www.joda.org/joda-time/
źródło
Zdecydowanie nie jest to najbardziej poprawny sposób, ale jeśli potrzebujesz szybkiego rozwiązania, aby uzyskać datę bez czasu i nie chcesz korzystać z biblioteki innej firmy, powinno to zrobić
Potrzebowałem tylko daty do celów wizualnych i nie mogłem Joda, więc podłożyłem.
źródło
źródło
O ile wiem, nie ma łatwiejszego sposobu na osiągnięcie tego, jeśli używasz tylko standardowego JDK.
Możesz oczywiście umieścić tę logikę w metodzie 2 w funkcji statycznej w klasie pomocniczej, tak jak zrobiono to tutaj w metodzie toBeginningOfTheDay
Następnie możesz skrócić drugą metodę do:
Lub, jeśli naprawdę tak często potrzebujesz bieżącego dnia w tym formacie, możesz po prostu zawinąć go w inną statyczną metodę pomocniczą, czyniąc go w ten sposób liniowym.
źródło
Jeśli chcesz tylko zobaczyć datę „RRRR-MM-DD” bez innych bałaganu, np. „Cz 21 maja 12:08:18 EDT 2015”, po prostu użyj
java.sql.Date
. Ten przykład pobiera bieżącą datę:Również
java.sql.Date
jest podklasąjava.util.Date
.źródło
Jeśli potrzebujesz tylko bieżącej daty, bez czasu, inną opcją jest:
źródło
00:00:00
zwykle jest czasem (może się różnić w zależności od strefy czasowej dla anomalii, takich jak czas letni ). Tak więc, jak zauważają inne Odpowiedzi,LocalDate
klasa jest bardziej odpowiednia, od Joda-Time (zakładając, że odwołujesz się do Joda-Time - na co powinieneś wyraźnie zwrócić uwagę przy cytowaniu klas niepowiązanych z Javą).Użyj
LocalDate.now()
i przekonwertuj naDate
poniższe:źródło
TimeZone.setDefault
. Twój kod wywołuje sięZoneId.systemDefault
dwa razy, pierwszy jest domyślnie ukryty,LocalDate.now()
a drugi jawnie za pomocąatStartOfDay
. Pomiędzy tymi dwoma momentami w czasie wykonywania bieżąca domyślna strefa może się zmienić. Sugeruję uchwycenie strefy w zmiennej i przejście do obu metod.Jeśli potrzebujesz części daty tylko w celu uzyskania echa, to
źródło
A co z tym?
źródło
Sprawdź czas Veyder . Jest to prosta i wydajna alternatywa zarówno dla java.util, jak i Joda-time. Ma intuicyjny interfejs API i klasy, które reprezentują same daty, bez znaczników czasu.
źródło
Najprostszy sposób, który w pełni wykorzystuje ogromną bazę danych TimeZone Java i jest poprawny:
źródło
Oto czyste rozwiązanie bez konwersji na ciąg znaków i wstecz, a także nie oblicza czasu kilka razy, gdy resetujesz każdy składnik czasu do zera. Wykorzystuje również
%
(moduł) zamiast dzielenia, a następnie mnożenia, aby uniknąć podwójnej operacji.Nie wymaga żadnych zależności od stron trzecich i SZANUJE PRZESTRZEŃ CZASOWĄ przekazanego obiektu kalendarza. Ta funkcja zwraca moment o godzinie 12 w strefie czasowej daty (kalendarza), którą podajesz.
źródło
Wolisz nie korzystać z bibliotek stron trzecich w jak największym stopniu. Wiem, że o tym wcześniej wspominano, ale tutaj jest ładny, czysty sposób:
Cóż, nie używanie GregorianCalendar może być opcją!
źródło
Właśnie zrobiłem to dla mojej aplikacji:
Android API poziom 1, brak biblioteki zewnętrznej. Przestrzega światła dziennego i domyślnej strefy czasowej. Bez manipulacji ciągiem, więc myślę, że ten sposób jest bardziej wydajny niż procesor, ale nie wykonałem żadnych testów.
źródło
Możesz użyć czasu Joda.
i dzwonisz z:
źródło