Mam obiekt Java Date zawierający informacje o dacie i godzinie. Chcę napisać metodę, która odcina informacje o czasie, skraca godziny-minuty-sekundy, więc została mi tylko data.
Przykładowe dane wejściowe:
2008-01-01 13:15:00
Oczekiwany wynik:
2008-01-01 00:00:00
Masz wskazówkę? Próbowałem zrobić coś takiego:
(timestamp / (24 * 60 * 60 * 1000)) * (24 * 60 * 60 * 1000)
ale napotkałem problemy ze strefą czasową.
java.util.Calendar
obecnie starsze , zastąpione przez klasy java.time . Zobacz samouczek firmy Oracle .Czy spojrzałeś na metodę obcinania DateUtils w Apache Commons Lang?
usunie element czasu.
źródło
Spojrzałeś na Jodę ? To znacznie łatwiejszy i bardziej intuicyjny sposób pracy z datami i godzinami. Na przykład możesz konwertować trywialnie między (powiedzmy) obiektami LocalDateTime i LocalDate .
np. (aby zilustrować API)
Dodatkowo rozwiązuje niektóre problemy z bezpieczeństwem wątków z formatami daty / czasu i jest zdecydowanie zalecany do pracy z wszelkimi problemami z datą / godziną w Javie.
źródło
Tylko szybka aktualizacja w świetle klas java.time wbudowanych teraz w Javę 8 i nowszą.
LocalDateTime
matruncatedTo
metodę, która skutecznie rozwiązuje to, o czym tutaj mówisz:To wyrazi aktualny czas tylko do minut:
Możesz użyć
ChronoUnit
(lub aTemporalUnit
) mniejszego niż DAYS do wykonania obcięcia (ponieważ obcięcie jest stosowane tylko do części czasu LocalDateTime, a nie do części daty).źródło
źródło
Z Jodą możesz łatwo uzyskać oczekiwany termin.
Od wersji 2.7 (być może od jakiejś poprzedniej wersji wyższej niż 2.2), jak zauważa komentator,
toDateMidnight
został uznany za przestarzały na korzyść lub trafnie nazwanywithTimeAtStartOfDay()
, co czyni wygodnymmożliwy.
Dodana korzyść w postaci ładniejszego API.
Ze starszymi wersjami możesz to zrobić
źródło
withTimeAtStartOfDay
.toLocalDate
aby uzyskać obiekt, który nie ma nawet składnika czasu.Zrobiłem obcięcie z nowym API java8. Spotkałem się z jedną dziwną rzeczą, ale ogólnie jest okrojona ...
źródło
Użyj DateUtils z Apache, z obcięciem, w ten sposób:
źródło
W przypadku sygnatur czasowych:
źródło
Z java.util.Date JavaDocs:
i z java.sql.Date JavaDocs:
Dlatego najlepszym podejściem jest użycie java.sql.Date, jeśli nie potrzebujesz części czasu
a wynik to:
źródło
tl; dr
Aby wygenerować ciąg w żądanym formacie, przekaż plik
DateTimeFormatter
.Detale
Inne odpowiedzi są poprawne, ale używaj starych klas daty i czasu, które są obecnie przestarzałe przez strukturę java.time.
java.time
Struktura java.time jest wbudowana w Javę 8 i nowsze. Znaczna część funkcjonalności java.time jest przenoszona z powrotem do Java 6 i 7 ( ThreeTen-Backport ) i dalej dostosowywana do Androida ( ThreeTenABP ).
Najpierw zmień ciąg wejściowy, aby był zgodny z kanoniczną wersją formatu ISO 8601. Standardowe formaty ISO 8601 są używane domyślnie w klasach java.time do analizowania / generowania łańcuchów reprezentujących wartości daty i godziny. Musimy zastąpić tę SPACJĘ w środku a
T
.Teraz możemy go przeanalizować jako
LocalDateTime
, gdzie „Lokalny” oznacza brak określonej lokalizacji. Dane wejściowe nie zawierają żadnych informacji o przesunięciu względem czasu UTC ani o strefie czasowej.Jeśli nie interesuje Cię pora dnia ani strefa czasowa, przekonwertuj na plik
LocalDate
.Pierwsza chwila dnia
Jeśli zamiast tego chcesz, aby godzina była ustawiona na pierwszą porę dnia, użyj
ZonedDateTime
klasy, a następnie przekonwertuj naLocalDate
obiekt, aby wywołać jegoatStartOfDay
metodę. Należy pamiętać, że pierwsza chwila może nie00:00:00
nadejść z powodu czasu letniego lub innych anomalii.Strefa czasowa ma kluczowe znaczenie, ponieważ w dowolnym momencie data różni się na całym świecie według strefy. Na przykład, kilka chwil po północy w Paryżu to nowy dzień dla paryżan, ale dla Kanadyjczyków wciąż jest to „wczoraj” w Montrealu.
UTC
Aby zobaczyć ten moment przez pryzmat strefy czasowej UTC , wyodrębnij
Instant
obiekt. ZarównoZonedDateTime
i, jak iInstant
będą reprezentować ten sam moment na osi czasu, ale pojawią się jako dwa różne czasy na zegarze ściennym .An
Instant
jest podstawową klasą bloków konstrukcyjnych w java.time, z definicji zawsze w UTC. Używaj tej klasy często, ponieważ generalnie powinieneś wykonywać logikę biznesową, przechowywanie danych i wymianę danych w UTC.Widzimy 5 rano zamiast wybicia północy. W standardowym formacie,
Z
na końcu jest skrótemZulu
i oznacza „UTC”.Informacje o java.time
Struktura java.time jest wbudowana w Javę 8 i nowsze. Klasy te kłopotliwe zastąpić stary starszych klas Date-Time, takich jak
java.util.Date
,Calendar
, iSimpleDateFormat
.Projekt Joda-Time , obecnie w trybie konserwacji , zaleca migrację do klas java.time .
Aby dowiedzieć się więcej, zobacz samouczek Oracle . I przeszukaj Stack Overflow, aby znaleźć wiele 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 ma potrzeby stosowania ciągów ani
java.sql.*
klas.Skąd wziąć 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
Użyj metody klasy Calendar ,
set()
aby ustawić polaHOUR_OF_DAY, MINUTE, SECOND
iMILLISECOND
na zero.źródło
Pytanie jest sprzeczne. Pyta o datę bez godziny, ale wyświetla przykład z godziną
00:00:00
.Joda-Time
AKTUALIZACJA: Projekt Joda-Time jest teraz w trybie konserwacji , a zespół zaleca migrację do klas java.time . Zobacz moją drugą odpowiedź dotyczącą rozwiązania java.time.
Jeśli zamiast tego chcesz ustawić porę dnia na pierwszą porę dnia, użyj
DateTime
obiektu w bibliotece Joda-Time i wywołaj jegowithTimeAtStartOfDay
metodę. Należy pamiętać, że pierwsza chwila może nie00:00:00
nadejść z powodu czasu letniego lub innych anomalii.źródło
Tylko
clear()
zbędne pola.Od Java 8 lepszym rozwiązaniem jest użycie
truncatedTo
metodyLocalDateTime
np:źródło
calendar.clear(Calendar.HOUR_OF_DAY);
nie odlicza godzin. Rozwiązanie z @cletus działa OK.Naprawdę zirytowało mnie to, że nowy „ulepszony” konstruktor kalendarza nie przyjmuje int przez milisekundy, jak „okropny” stary Date one. Wtedy naprawdę się zdenerwowałem i napisałem to:
Nie użyłem wtedy słowa „rzeczy”, ale potem odkryłem szczęście:
Ale nadal jestem z tego powodu zły.
źródło
Rozwiązałem problem w ten sposób (w ósmej strefie wschodniej (czas pekiński)):
Przede wszystkim powinieneś wiedzieć, co to jest znacznik czasu. Znacznik czasu to całkowita liczba milisekund od 01 stycznia 00:00:00 1970 GMT (tak samo jak UTC) lub od czwartku 01 stycznia 08:00:00 CST 1970 do teraz.
Pamiętaj: znacznik czasu jest niezależny od strefy czasowej.
Tak więc otrzymujesz ten sam wynik z poniższą instrukcją w różnych strefach czasowych:
I
wyświetla różne informacje o czasie w różnych strefach czasowych: jeśli ustawisz strefę czasową swojego komputera na UTC, otrzymasz
Ale jeśli ustawisz strefę czasową na (UTC +8: 00) Beijing, Chongqing, HongKong, Urumq, otrzymasz:
Java pobiera sygnaturę czasową, a następnie wyświetla informacje o dacie i godzinie według strefy czasowej.
Aby dowiedzieć się, jak Java wyświetla informacje o dacie i godzinie w różnych strefach czasowych, sposób transkacji informacji o czasie jest łatwy. Powinieneś otrzymać sygnaturę czasową i wziąć pod uwagę strefę czasową, gdy odcinasz informacje o czasie. Następnie możesz utworzyć nowy obiekt Date z wyciętym znacznikiem czasu (możemy to nazwać datownikiem), java skompensuje strefę czasową, gdy wyświetla informacje o dacie.
Podobnie jak w ósmej strefie wschodniej (czas pekiński), czas w Pekinie jest wcześniejszy o 8 godzin niż GMT, więc podczas wykonywania operacji modulo należy odjąć więcej 8 godzin. Oznacza to, że najpierw powinieneś uzyskać czas GMT, a następnie Java doda 8 godzin do czasu wyświetlania w oparciu o ustawienie strefy czasowej komputera.
Kwestia strefy czasowej jest niejasna i przez długi czas mnie intryguje. Teraz wyjaśniam to jasno. Nadzieja pomaga.
2018-01-04 Działa również poniższa metoda.
}
źródło
Możesz to zrobić, aby uniknąć problemów ze strefą czasową:
Chociaż
Date
obiekt Java jest wartością znacznika czasu, ale podczas obcięcia zostanie przekonwertowany na lokalną strefę czasową, więc uzyskasz zaskakującą wartość, jeśli spodziewasz się wartości ze strefy czasowej UTC.źródło
Calendar
iDate
klasy stały się starsze lata temu wraz z klasami java.time implementującymi JSR 310 w Javie 8 i nowszych. Sugerowanie ich użycia w 2018 roku to kiepska rada.Może to być spóźniona odpowiedź, ale oto sposób na zrobienie tego w jednej linii bez korzystania z żadnych bibliotek:
źródło
Z Joda-Time od wersji 2.0 możesz używać
LocalDate.toDate()
.Po prostu
źródło
a Java Date object
więc użyłemjava.util.Date
. Co więcej, nie wyjaśnia, dlaczego jego strefa czasowa jest problematyczna z java.util.Date (kiedy? Gdzie?), Chociaż nie może pomóc w korzystaniu z innego niżDate
.W przypadku wszystkich odpowiedzi korzystających z Kalendarza powinieneś używać go w ten sposób
Ale wolę to:
źródło
java.sql.Date
Klasa udaje reprezentować wartości daty-ale tylko faktycznie ma time-of-day skorygowanej o UTC strefy czasowej. Więc nie jest to właściwe rozwiązanie tego pytania.Oto prosty sposób na uzyskanie daty bez godziny, jeśli używasz języka Java 8+: użyj typu java.time.LocalDate zamiast Date.
Wyjście:
https://docs.oracle.com/javase/8/docs/api/java/time/LocalDate.html
źródło
LocalDate
jest dobrym pomysłem dla większości zastosowań, ale nie wiadomo, jak to będzie działać z wejściem z pytaniem2008-01-01 13:15:00
.