jak utworzyć obiekt Java Date o północy dzisiaj i północy jutro?

178

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();
ROMANIA_inżynier
źródło
3
Moim zdaniem Joda Time jest łatwiejsza, spójrz na koniec mojej odpowiedzi. Jeśli chcesz użyć java.util.Date/Calendar, musisz to zrobić w ten sposób, nie ma prostszego sposobu, aby to zrobić.
timaschew
RE: timas unikaj komentarza, aby użyć Joda-Time, wiedz, że projekt Joda-Time jest teraz w trybie konserwacji, i zaleca migrację do klas java.time.
Basil Bourque,
1
Do Twojej wiadomości, strasznie kłopotliwe stare klasy daty i czasu, takie jak java.util.Date, java.util.Calendari java.text.SimpleDateFormatsą teraz spuścizną , wyparte przez klasy java.time wbudowane w Javę 8 i nowsze wersje . Zobacz samouczek Oracle .
Basil Bourque,
2
Rzadko widuje się tak wiele błędnych odpowiedzi na pytanie, jak na to pytanie. Polecam odpowiedź Basil Bourque , jest poprawna i kompetentna.
Ole VV

Odpowiedzi:

344

java.util.Calendar

// today    
Calendar date = new GregorianCalendar();
// reset hour, minutes, seconds and millis
date.set(Calendar.HOUR_OF_DAY, 0);
date.set(Calendar.MINUTE, 0);
date.set(Calendar.SECOND, 0);
date.set(Calendar.MILLISECOND, 0);

// next day
date.add(Calendar.DAY_OF_MONTH, 1);

JDK 8 - java.time.LocalTime i java.time.LocalDate

LocalTime midnight = LocalTime.MIDNIGHT;
LocalDate today = LocalDate.now(ZoneId.of("Europe/Berlin"));
LocalDateTime todayMidnight = LocalDateTime.of(today, midnight);
LocalDateTime tomorrowMidnight = todayMidnight.plusDays(1);

Joda-Time

Jeśli używasz JDK <8, polecam Joda Time , ponieważ interfejs API jest naprawdę ładny:

DateTime date = new DateTime().toDateMidnight().toDateTime();
DateTime tomorrow = date.plusDays(1);

Ponieważ wersja 2.3 Joda Time DateMidnightjest przestarzała , użyj tego:

DateTime today = new DateTime().withTimeAtStartOfDay();
DateTime tomorrow = today.plusDays(1).withTimeAtStartOfDay();

Podaj strefę czasową, jeśli nie chcesz bieżącej domyślnej strefy czasowej JVM.

DateTimeZone timeZone = DateTimeZone.forID("America/Montreal");
DateTime today = new DateTime(timeZone).withTimeAtStartOfDay(); // Pass time zone to constructor.
unikaj czasu
źródło
Dzięki za pomoc, właśnie zaktualizowałem swoje pierwotne pytanie o to, jak obecnie to robię. Dzieki za sugestie.
3
Od wersji JodaTime 2.3 toDateMidnightjest przestarzały. Zobacz tę odpowiedź, aby uzyskać szczegółowe informacje: stackoverflow.com/a/19048833/363573
Stephan
dodano rozwiązanie dla JDK 8
timaschew
1
@timaschew Chociaż ogólnie poprawne, sugeruję wykonanie java.time przy użyciu strefowej wartości data-czas ( ZonedDateTime), tak jak w sekcji Joda-Time. Te Local…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.
Basil Bourque,
1
@Amalgovinus Upewnij się, że ustawiłeś Calendar.HOUR_OF_DAY, a nie Calendar.HOUR.
Oswald
43

Dla kompletności, jeśli używasz Java 8 , możesz również użyć truncatedTometody Instantklasy, aby uzyskać północ w UTC .

Instant.now().truncatedTo(ChronoUnit.DAYS);

Jak napisano w Javadoc

Na przykład obcięcie za pomocą jednostki MINUTES zaokrągli w dół do najbliższej minuty, ustawiając sekundy i nanosekundy na zero.

Mam nadzieję, że to pomoże.

riccardo.cardin
źródło
1
Dzięki za podpowiedź. Uzyskanie północy w określonej strefie czasowej staje się dłuższe:Date.from(date.toInstant().atZone(ZoneId.systemDefault()).truncatedTo(ChronoUnit.DAYS).toInstant())
Vadzim
33

Najłatwiejszy sposób na znalezienie północy:

Long time = new Date().getTime();
Date date = new Date(time - time % (24 * 60 * 60 * 1000));

Następny dzień:

Date date = new Date(date.getTime() + 24 * 60 * 60 * 1000);
Andrei Volgin
źródło
Uruchomiłem ten kod i dostałem: Północ: 01 listopada 19:00:00 CDT 2012
Dave
3
Jeśli zrobiłeś coś takiego jak System.out.print (data), system przekształcił instancję daty w systemową strefę czasową (CDT). 19:00 w CDT jest północ w GMT. Jeśli potrzebujesz północy w wybranej strefie czasowej, musisz dodać przesunięcie tej strefy czasowej, biorąc pod uwagę czas letni.
Andrei Volgin
@ Bramkarz Jest. Na Ziemi istnieje wiele różnych „północy” bez względu na to, z której metody korzystasz, ale jest tylko jedna północ Java.
Andrei Volgin
2
@Andrei Volgin Nie wiedziałem, że istnieje „java północ”. ;) To, co chciałem powiedzieć, że to rozwiązanie naprawdę nie pomaga twórcy tematu. Rozwiązanie kalendarza pozwala uniknąć brzydkich drugich obliczeń i dba o strefy czasowe (a zwłaszcza czasy oszczędzania światła dziennego itp.), Jeśli są właściwie używane. Nie widzę tego w twoim rozwiązaniu.
Bouncner
Cześć @AndreiVolgin, Mam datę Data = nowa Data (czas + TimeZone.getDefault (). GetRawOffset () - czas% (24 * 60 * 60 * 1000));
Jrey
28

Pamiętaj, Datenie jest używany do reprezentowania dat (!). Aby przedstawić datę, potrzebujesz kalendarza. To:

Calendar c = new GregorianCalendar();

utworzy Calendarinstancję 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 na 0. Masz dziś północ.

Teraz, aby uzyskać północ następnego dnia, musisz dodać jeden dzień:

c.add(Calendar.DAY_OF_MONTH, 1);

Pamiętaj, że dodanie 86400sekund 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 :

Date start = DateUtils.truncate(new Date(), Calendar.DAY_OF_MONTH))
Date end = DateUtils.addDays(start, 1);

To używa Calendar za kulisami ...

Tomasz Nurkiewicz
źródło
15
Dzięki za pomoc. „Data nie jest używana do reprezentowania dat” - to dziwne, genialne, prawda? ;)
@RobertHume Aby być uczciwym, data jest dostępna od pierwszego wydania Java. Większość rzeczy z tej epoki jest ... mniej niż doskonale przemyślana. Zwłaszcza, że ​​Java była jedną z pierwszych osób, które próbowały tego, czego próbowała, i daleko było do uzgodnionego standardu, jak to zrobić.
Pozew funduszu Moniki z
14

te metody pomogą ci-

public static Date getStartOfDay(Date date) {
     Calendar calendar = Calendar.getInstance();
     calendar.setTime(date);
     calendar.set(Calendar.HOUR_OF_DAY, 0);
     calendar.set(Calendar.MINUTE, 0);
     calendar.set(Calendar.SECOND, 0);
     calendar.set(Calendar.MILLISECOND, 0);
     return calendar.getTime();
 }

i

public static Date getEndOfDay(Date date) {
    Calendar calendar = Calendar.getInstance();
    calendar.setTime(date);
    calendar.set(Calendar.HOUR_OF_DAY, 23);
    calendar.set(Calendar.MINUTE, 59);
    calendar.set(Calendar.SECOND, 59);
    calendar.set(Calendar.MILLISECOND, 999);
    return calendar.getTime();
}
Visvendra Singh Rajpoot
źródło
9

Począwszy od JodaTime 2.3, toDateMidnight()jest przestarzały.

Z aktualizacji z 2.2 na 2.3

    Odstąpienia od 2.2
    ----------------------
    - DateMidnight [# 41]
     Ta klasa ma wadę koncepcyjną
     Czas północy czasami nie występuje w niektórych strefach czasowych
     Jest to wynik czasu letniego od 00:00 do 01:00
     DateMidnight to zasadniczo DateTime z czasem zablokowanym do północy
     Taka koncepcja jest bardziej kiepska w użyciu, biorąc pod uwagę LocalDate
     Zamień DateMidnight na LocalDate
     Lub zamień go na DateTime, być może przy użyciu metody withTimeAtStartOfDay ()

Oto przykładowy kod bez toDateMidnight()metody.

Kod

DateTime todayAtMidnight = new DateTime().withTimeAtStartOfDay();
System.out.println(todayAtMidnight.toString("yyyy-MM-dd HH:mm:ss"));

Dane wyjściowe ( mogą się różnić w zależności od lokalnej strefy czasowej )

2013-09-28 00:00:00
Stephan
źródło
2
Doskonała odpowiedź. Dodałbym przekazanie DateTimeZoneinstancji do tego DateTimekonstruktora, 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" );
Basil Bourque
9

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ędzie 23: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:

… Od dzisiaj o 00:00 (północ wcześnie rano) do 12:00 (północ dziś wieczorem).

… Pomyśl tak…

od pierwszego momentu dzisiejszego dnia do pierwszego dnia jutra, ale nie wliczając pierwszego:
(> = 00:00:00.0dzisiaj ORAZ < 00:00:00.0jutro)

W pracy bazy danych, podejście to znaczy nie za pomocą BETWEENoperatora 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ć LocalDatei wrócić do, ZonedDateTimejak widać w tym przykładowym kodzie.

ZoneId zoneId = ZoneId.of( "America/Montreal" );
ZonedDateTime now = ZonedDateTime.now( zoneId );
ZonedDateTime todayStart = now.toLocalDate().atStartOfDay( zoneId );
ZonedDateTime tomorrowStart = todayStart.plusDays( 1 );

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.

java.util.Date utilDate = java.util.Date.from( todayStart.toInstant() );
java.util.GregorianCalendar gregCal = java.util.GregorianCalendar.from( todayStart );

Przedział czasu

Nawiasem mówiąc, jeśli wykonujesz dużo pracy z upływem czasu, spójrz na:

  • Duration
  • Period
  • Interval
    IntervalKlasa 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, i SimpleDateFormat.

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 .

Basil Bourque
źródło
6

java.time

Jeśli używasz języka Java 8 i nowszych, możesz wypróbować pakiet java.time ( samouczek ):

LocalDate tomorrow = LocalDate.now().plusDays(1);
Date endDate = Date.from(tomorrow.atStartOfDay(ZoneId.systemDefault()).toInstant());
arganzheng
źródło
2
Dobra odpowiedź. Sugerowałbym określenie pożądanej / oczekiwanej strefy czasowej. Bieżąca domyślna strefa czasowa JVM może się różnić w zależności od ustawień systemu operacyjnego, zmiany komputerów lub dowolnej aplikacji w dowolnym wątku JVM zmieniającej wartość domyślną w dowolnym momencie podczas działania.
Basil Bourque,
4

To wydaje się być opcją:

DateFormat justDay = new SimpleDateFormat("yyyyMMdd");
Date thisMorningMidnight = justDay.parse(justDay.format(new Date()));

aby dodać do tego dzień

Date tomorrow = new Date(thisMorningMidnight.getTime() + 24 * 60 * 60 * 1000);

lub

Calendar c = Calendar.getInstance();
c.setTime(thisMorningMidnight);
c.add(Calendar.DATE, 1);
Date tomorrowFromCalendar = c.getTime();

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).

rogerdpack
źródło
Mam datę i godzinę reprezentowaną przez długi czas w mojej bazie danych sqlite. Muszę długo czekać na początek następnego dnia. Czy nadal mogę używać obiektu Date z moim długim zamiast z metodą SimpleDateFormat, której używasz powyżej?
AJW,
1
Tak długo, jak jest to właściwa milisekunda, możesz przekazać go jako konstruktor: docs.oracle.com/javase/7/docs/api/java/util/…
rogerdpack
1

Zrobiłem to inaczej niż wszyscy tutaj. Jestem nowy w Javie, więc może moje rozwiązanie jest złe.

Date now = new Date();
Date midnightToday = new Date(now.getYear(), now.getMonth(), now.getDate());

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:

c.add(Calendar.DAY_OF_MONTH, 1);

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.

Mitch
źródło
2
Cześć Mitch. Myślę, że twoje rozwiązanie działa, ale wygląda na to, że konstruktor Date jest przestarzały. Ludzie z Java wycofali większość pierwotnych metod związanych z datą i zastąpili je nowszymi metodami związanymi z kalendarzem. Osobiście nie rozumiem, jak to jest poprawa, ale niechętnie używa przestarzałych metod. Dzięki!
Smutne z powodu rezygnacji. Wydaje mi się znacznie łatwiejsze określenie roku, miesiąca i daty niż usuwanie godziny, minuty, sekundy i milisekund. Ich usunięcie polega na tym, że milisek to najdrobniejsza szczegółowość klasy Date, podczas gdy moje rozwiązanie tego nie robi. Moje rozwiązanie jest również krótsze i jaśniejsze. Jako, że jestem nowy w Javie, naprawdę doceniam to, jak czyste, łatwe i wydajne jest C ++, jeśli chodzi o używanie dat i godzin.
Mitch
@Mitch Z mojego doświadczenia wynika, że ​​najnowszy język, którego się uczysz, jest zawsze postrzegany jako najbardziej skomplikowany.
ArtOfWarfare
Do waszej informacji: te cholernie okropne, stare klasy randkowe są teraz dziedzictwem, wyparte przez nowoczesne klasy java.time.
Basil Bourque,
0

Najprostszy sposób z JodaTime

DateMidnight date = DateMidnight.now();

Javier Sculli
źródło
2
Nie. Wszystkie klasy i metody związane z „północą” zostały przestarzałe. Oparte były na błędnej koncepcji. Pierwsza chwila dnia nie zawsze jest 00:00:00.000. Zamiast tego użyj nowej withTimeAtStartOfDaymetody. Zaktualizuj do aktualnej wersji 2.4 Joda-Time i przeczytaj informacje o wersji. Przykład:DateTime today = DateTime.now( DateTimeZone.forID( "America/Montreal" ) ).withTimeAtStartOfDay();
Basil Bourque,
0

Ponieważ jeden dzień to 24 * 60 * 60 * 1000ms, północ tego dnia można obliczyć jako ...

long now = System.currentTimeMillis();
long delta = now % 24 * 60 * 60 * 1000;
long midnight = now - delta;
Date midnightDate = new Date(midnight);`
lshu
źródło
1
Ten kod dotyczy tylko UTC i żadnej innej strefy czasowej i ignoruje anomalie, takie jak czas letni. Co więcej, wprowadzanie własnych rozwiązań daty i czasu jest nierozsądne, ponieważ jest to zaskakująco trudny temat. Zamiast tego użyj doskonałych klas java.time.
Basil Bourque
0

Prawie jak wcześniej, ale nikt nie wspomniał o parametrze AM_PM:

    Calendar cal = Calendar.getInstance();
    cal.set(Calendar.HOUR, 0);
    cal.set(Calendar.MINUTE, 0);
    cal.set(Calendar.SECOND, 0);
    cal.set(Calendar.MILLISECOND, 0);
    cal.set(Calendar.AM_PM, Calendar.AM);
Montaser
źródło
1
Kłopotliwa Calendarklasa została zastąpiona wiele lat temu przez klasy java.timeZonedDateTime .
Basil Bourque,
0
Date now= new Date();
// Today midnight
Date todayMidnight = new Date(endTime.getTime() -endTime.getTime()%DateUtils.MILLIS_PER_DAY);

// tomorrow midnight
Date tomorrowMidnight = new Date(endTime.getTime() -endTime.getTime()%DateUtils.MILLIS_PER_DAY + DateUtils.MILLIS_PER_DAY);
gzg_55
źródło
Działa to tylko w przypadku UTC i nie odnosi się do stref czasowych. Ta straszna Dateklasa została wyparta przez lata temu java.time.Instant. Unikaj korzystania w Datedzisiejszych czasach.
Basil Bourque,
0

Używanie wspólnego apache ..

//For midnight today 
Date today = new Date(); 
DateUtils.truncate(today, Calendar.DATE);

//For midnight tomorrow   
Date tomorrow = DateUtils.addDays(today, 1); 
DateUtils.truncate(tomorrow, Calendar.DATE);
joe4java
źródło
Do Twojej wiadomości, strasznie kłopotliwe stare klasy daty i czasu, takie jak java.util.Date, java.util.Calendari java.text.SimpleDateFormatsą teraz spuścizną , wyparte przez klasy java.time wbudowane w Javę 8 i nowsze wersje . Zobacz samouczek Oracle .
Basil Bourque
@BasilBourque zgodził się na Javę 8. Ale jeśli OP używa Java 7, myślę, że nadal by to działało.
joe4java
Prawie cała funkcjonalność java.time jest dostępna dla Java 6 i 7 w projekcie ThreeTen-Backport z praktycznie identycznym API. Dalsze dostosowanie do Androida <26 w projekcie ThreeTenABP . Więc nie trzeba już nigdy używać tych nieszczęsnych, starych klas daty i czasu.
Basil Bourque
-1

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

public static Date getCurrentDateWithMidnightTS(){

    return new Date(System.currentTimeMillis() - (System.currentTimeMillis()%(1000*60*60*24)) - (1000*60 * 330));
}

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.

Rajeev
źródło
1
Dlaczego sugerowałbyś to zamiast zaakceptowanej odpowiedzi? Generowanie wartości daty i godziny jest ogólnie ryzykowne. W szczególności ten kod jest na zawsze zakodowany na stałe w bieżącym przesunięciu pojedynczej strefy czasowej. Nie ma uwzględnienia czasu letniego ani innych anomalii. Widzę tylko wady bez żadnej wartości dodanej.
Basil Bourque
@Basil oczywiście akceptuję odpowiedź i tak, wspomniałem tam o wartości zakodowanej na stałe. Jest to pomocne tylko w przypadku pracy w określonej strefie czasowej.
Rajeev
-1
Date todayMidnightUTC = java.sql.Date.valueOf(LocalDate.now());
Date tomorrowMidnightUTC = java.sql.Date.valueOf(LocalDate.now().plusDays(1));
Date anyMidnightLocal = java.sql.Date.valueOf(LocalDate.from(dateTime.toInstant().atZone(ZoneId.systemDefault())));

Ale uwaga, że java.sql.Date.toInstant()zawsze rzuca UnsupportedOperationException.

Przez LocalDate do java.util.Date i odwrotnie, najprostsza konwersja?

Wadzim
źródło
Niezbyt dobra odpowiedź. Mieszasz korzystanie z nowoczesnego java.time ze starymi klasami, które zastępują. W szczególności korzystasz z klas daty i godziny java.sql, które powinny być używane tylko do wymiany danych z bazą danych, której sterownik nie został jeszcze zaktualizowany do bezpośredniego zarządzania klasami java.time, nigdy do użycia w logice biznesowej. Kolejny problem polega na tym, że ignorujesz kluczową kwestię strefy czasowej.
Basil Bourque,
@BasilBourque, dzięki za krytykę. Korzystanie z jednej klasy starszej, która nie jest oznaczona jako przestarzała, w celu uzyskania innej instancji klasy starszej jest całkiem bezpieczne. Kwestia strefy czasowej jest ważniejsza. W końcu postanowiłem trzymać się odpowiedzi Riccardo .
Vadzim
-1

Po staremu..

private static Date getDateWithMidnight(){
    long dateInMillis = new Date().getTime();
    return new Date(dateInMillis - dateInMillis%(1000*60*60*24) - TimeZone.getDefault().getOffset(dateInMillis));
}
Prabath
źródło
Ta kłopotliwa klasa została zastąpiona przed laty przez java.time.Instant . Nie musisz nigdy używać Date.
Basil Bourque,
Ta Dateklasa 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.
Basil Bourque,