como criar um objeto Java Date da meia-noite de hoje e da meia-noite de amanhã?

178

No meu código, preciso encontrar todas as minhas coisas que aconteceram hoje. Então, preciso comparar com as datas de hoje às 00:00 (meia-noite desta manhã) e às 12:00 (meia-noite de hoje à noite).

Eu sei ...

Date today = new Date(); 

... me pega agora. E ...

Date beginning = new Date(0);

... me dá tempo zero em 1º de janeiro de 1970. Mas qual é a maneira mais fácil de obter tempo zero hoje e amanhã amanhã?

ATUALIZAR; Eu fiz isso, mas certamente há uma maneira mais fácil?

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_engineer
fonte
3
Na minha opinião Joda Time é mais fácil, veja o final da minha resposta. Se você quiser usar o java.util.Date/Calendar, precisará fazê-lo dessa maneira, não há maneira mais fácil de fazê-lo.
timaschew
RE: timaschew comenta o uso do Joda-Time, saiba que o projeto Joda-Time agora está no modo de manutenção e aconselha a migração para as classes java.time.
Basil Bourque
1
FYI, os terrivelmente problemáticas aulas em tempo data antigas, tais como java.util.Date, java.util.Calendare java.text.SimpleDateFormatestão agora legado , suplantado pelos java.time classes internas em Java 8 e posterior. Consulte o Tutorial da Oracle .
Basil Bourque
2
Raramente há tantas respostas defeituosas a uma pergunta quanto a esta. Eu recomendo a resposta de Basil Bourque , é correta e experiente.
VV Ole VV

Respostas:

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 e 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

Se você estiver usando um JDK <8, recomendo o Joda Time , porque a API é muito boa:

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

Como a versão 2.3 do Joda Time DateMidnightestá obsoleta , use este:

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

Passe um fuso horário se não desejar o fuso horário padrão atual da JVM.

DateTimeZone timeZone = DateTimeZone.forID("America/Montreal");
DateTime today = new DateTime(timeZone).withTimeAtStartOfDay(); // Pass time zone to constructor.
timaschew
fonte
Obrigado pela ajuda, eu havia acabado de atualizar minha pergunta original com a forma como estava fazendo isso no momento. Obrigado pela sugestão.
3
A partir do JodaTime 2.3, toDateMidnightfoi preterido. Veja esta resposta para obter detalhes: stackoverflow.com/a/19048833/363573
Stephan
adicionou uma solução para JDK 8
timaschew 18/01/2015
1
@timaschew Embora geralmente correto, sugiro fazer o java.time usando um valor de data / hora ( ZonedDateTime) como você fez na seção Joda-Time. Os Local…tipos não têm informações de fuso horário - esse é seu objetivo inteiro, não perdem / ignoram todos os detalhes de deslocamento e fuso horário. Especialmente quando a Pergunta fala sobre o uso desses valores para comparação (talvez consultas ao banco de dados?), É provável que um valor de data / hora com zoneamento seja mais útil.
Basil Bourque
1
@Amalgovinus Certifique-se de definir Calendar.HOUR_OF_DAY, não Calendar.HOUR.
Oswald
43

Para garantir a integridade, se você estiver usando o Java 8, também poderá usar o truncatedTométodo da Instantclasse para obter meia-noite no UTC .

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

Conforme escrito no Javadoc

Por exemplo, truncar com a unidade MINUTES arredondará para o minuto mais próximo, configurando os segundos e os nanossegundos para zero.

Espero que ajude.

riccardo.cardin
fonte
1
Obrigado pela dica. Obtendo a meia-noite no fuso horário especificado fica mais longo:Date.from(date.toInstant().atZone(ZoneId.systemDefault()).truncatedTo(ChronoUnit.DAYS).toInstant())
Vadzim 29/06
33

A maneira mais fácil de encontrar uma meia-noite:

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

Próximo dia:

Date date = new Date(date.getTime() + 24 * 60 * 60 * 1000);
Andrei Volgin
fonte
Eu corri esse código e obtive: Meia-noite: Qui 01 de novembro 19:00:00 CDT 2012
Dave
3
Se você fez algo como System.out.print (date), o sistema converteu a instância de data no fuso horário do sistema (CDT). 19:00 no CDT é meia-noite no GMT. Se você precisar de meia-noite em um fuso horário selecionado, precisará adicionar o deslocamento desse fuso horário, levando em consideração o horário de verão.
Andrei Volgin
@Bouncner É. Existem muitos horários diferentes da 'meia-noite' na Terra, independentemente do método usado, mas há apenas uma meia-noite do Java.
Andrei Volgin
2
@Andrei Volgin Não sabia que existe uma "meia-noite java". ;) O que eu queria dizer é que essa solução realmente não ajuda o criador do tópico. Uma solução de calendário evita feios segundos cálculos e cuida dos fusos horários (e principalmente do horário de verão etc.) quando usados ​​adequadamente. Não vejo isso na sua solução.
Bouncner
Olá @AndreiVolgin, obtive com Date date = new Date (time + TimeZone.getDefault (). GetRawOffset () - time% (24 * 60 * 60 * 1000));
jrey
28

Lembre-se, Datenão é usado para representar datas (!). Para representar a data, você precisa de um calendário. Este:

Calendar c = new GregorianCalendar();

criará uma Calendarinstância representando a data atual no seu fuso horário atual. Agora, o que você precisa é truncar todos os campos abaixo do dia (hora, minuto, segundo e milissegundo) configurando-o para 0. Agora você tem meia-noite hoje.

Agora, para chegar à meia-noite do dia seguinte, você precisa adicionar um dia:

c.add(Calendar.DAY_OF_MONTH, 1);

Observe que a adição de 86400segundos ou 24 horas está incorreta devido ao horário de verão que pode ocorrer nesse meio tempo.

ATUALIZAÇÃO: No entanto, minha maneira favorita de lidar com esse problema é usar a classe DateUtils do Commons Lang :

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

Ele usa Calendarnos bastidores ...

Tomasz Nurkiewicz
fonte
15
Obrigado pela ajuda. "Data não é usada para representar datas" - nós vamos ser muito brilhantes, não é? ;)
@RobertHume Para ser justo, o Date existe desde o primeiro lançamento do Java. A maioria das coisas daquela época é ... menos do que perfeitamente pensada. Especialmente porque o Java foi um dos primeiros a tentar o tipo de coisas que estava tentando, e havia muito longe de um padrão acordado sobre como fazê-lo.
Fund Monica's Lawsuit
14

esses métodos ajudarão você-

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();
 }

e

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
fonte
9

A partir do JodaTime 2.3, o item toDateMidnight()foi descontinuado.

Da atualização de 2.2 para 2.3

    Descontinuações desde 2.2
    ----------------------
    - DateMidnight [# 41]
     Esta classe é falha de conceito
     Ocasionalmente, a hora da meia-noite não ocorre em alguns fusos horários
     Isso é resultado de um horário de verão das 00:00 às 01:00
     DateMidnight é essencialmente um DateTime com um horário bloqueado para meia-noite
     Geralmente, esse conceito é ruim, dado o LocalDate
     Substituir DateMidnight por LocalDate
     Ou substitua-o por DateTime, talvez usando o método withTimeAtStartOfDay ()

Aqui está um código de exemplo sem toDateMidnight()método.

Código

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

Saída ( pode ser diferente dependendo do fuso horário local )

2013-09-28 00:00:00
Stephan
fonte
2
Excelente resposta. Eu faria a adição de passar uma DateTimeZoneinstância para que DateTimeo construtor de salientar a importância de especificar um fuso horário em vez de, inadvertidamente, dependendo do padrão:DateTimeZone timeZone = DateTimeZone.forID( "Europe/Paris" );
Basil Bourque
9

Outras respostas estão corretas, especialmente a resposta java.time de arganzheng . Como alguns mencionados, você deve evitar as antigas classes java.util.Date/.Calendar, pois elas são mal projetadas, confusas e problemáticas. Eles foram suplantados pelas classes java.time.

Deixe-me adicionar notas sobre a estratégia de lidar com a meia - noite e os períodos de tempo .

Meio aberto

No trabalho de data e hora, os períodos de tempo são frequentemente definidos usando a abordagem "semi-aberta". Nesta abordagem, o começo é inclusivo, enquanto o final é exclusivo . Isso resolve problemas e, se usado de forma consistente, facilita muito o raciocínio sobre o manuseio de data e hora.

Um problema resolvido é definir o final do dia. O último momento do dia 23:59:59.999( milissegundos )? Talvez, na classe java.util.Date (do Java mais antigo; problemático - evite essa classe!) E na biblioteca de sucesso Joda-Time . Mas em outros softwares, como bancos de dados como o Postgres, o último momento será 23:59:59.999999( microssegundos ). Porém, em outros softwares, como o framework java.time (incorporado no Java 8 e posterior, sucessor do Joda-Time) e em alguns bancos de dados, como o H2 Database , o último momento pode ser 23:59.59.999999999( nanossegundos ). Em vez de dividir os cabelos, pense apenas no primeiro momento, não no último momento.

No Half-Open, um dia decorre do primeiro momento de um dia e vai até, mas não inclui, o primeiro momento do dia seguinte. Então, ao invés de pensar assim:

… A partir de hoje às 00:00 (meia-noite desta manhã) às 12:00 (meia-noite de hoje à noite).

... pense assim ...

desde o primeiro momento de hoje até o primeiro momento de amanhã, mas não incluindo:
(> = 00:00:00.0hoje AND < 00:00:00.0amanhã)

No trabalho de banco de dados, essa abordagem significa não usar o BETWEENoperador no SQL.

Início do dia

Além disso, o primeiro momento do dia nem sempre é a hora do dia 00:00:00.0. O horário de verão (DST) em alguns fusos horários e possivelmente em outras anomalias, pode significar que um horário diferente começa o dia.

Portanto, permita que as classes java.time façam o trabalho de determinar o início de um dia com uma chamada para LocalDate::atStartOfDay( ZoneId ). Portanto, temos que desviar LocalDatee voltar para, ZonedDateTimecomo você pode ver neste código de exemplo.

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

Observe a passagem do opcional ZoneId . Se omitido, o fuso horário padrão atual da sua JVM será aplicado implicitamente. Melhor ser explícito.

O fuso horário é crucial para o trabalho de data e hora. A pergunta e algumas outras respostas são potencialmente defeituosas porque não lidam conscientemente com o fuso horário.

Converter

Se você deve usar um java.util.Date ou .Calendar, procure novos métodos de conversão adicionados a essas classes antigas.

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

Período de tempo

A propósito, se você estiver fazendo muito trabalho com períodos de tempo, dê uma olhada:

  • Duration
  • Period
  • Interval
    A Intervalclasse é encontrada no projeto ThreeTen-Extra , uma extensão da estrutura java.time. Este projeto é o campo de prova para possíveis adições futuras ao java.time.
    Interval todayMontreal = Interval.of( todayStart.toInstant() , tomorrowStart.toInstant() );

Sobre java.time

A estrutura java.time é integrada ao Java 8 e posterior. Essas classes suplantar os velhos problemáticos legados aulas de data e hora, como java.util.Date, Calendar, e SimpleDateFormat.

O projeto Joda-Time , agora em modo de manutenção , aconselha a migração para as classes java.time .

Para saber mais, consulte o Tutorial do Oracle . E procure Stack Overflow para muitos exemplos e explicações. A especificação é JSR 310 .

Você pode trocar objetos java.time diretamente com seu banco de dados. Use um driver JDBC compatível com JDBC 4.2 ou posterior. Não há necessidade de strings, não há necessidade dejava.sql.* classes.

Onde obter as classes java.time?

O projeto ThreeTen-Extra estende java.time com classes adicionais. Este projeto é um campo de prova para possíveis adições futuras ao java.time. Você pode encontrar algumas classes úteis aqui, como Interval, YearWeek, YearQuarter, e mais .

Basil Bourque
fonte
6

java.time

Se você estiver usando o Java 8 e posterior, pode tentar o pacote java.time ( Tutorial ):

LocalDate tomorrow = LocalDate.now().plusDays(1);
Date endDate = Date.from(tomorrow.atStartOfDay(ZoneId.systemDefault()).toInstant());
arganzheng
fonte
2
Boa resposta. Eu sugeriria especificar o fuso horário desejado / esperado. O fuso horário padrão atual da JVM pode variar de acordo com as configurações do SO, a alteração de computadores ou qualquer aplicativo em qualquer encadeamento da JVM, alterando o padrão a qualquer momento durante o tempo de execução.
Basil Bourque
4

Parece ser uma opção:

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

para adicionar um dia a ele,

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

ou

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

Eu tenho um palpite de que o último é o preferido em caso de algo estranho como o horário de verão, fazendo com que adicionar 24 horas não seja suficiente (consulte https://stackoverflow.com/a/4336131/32453 e suas outras respostas).

rogerdpack
fonte
Eu tenho uma data e hora do dia representadas como um longo no meu banco de dados sqlite. Eu preciso demorar muito para o começo do dia seguinte. Ainda posso usar um objeto Date com meu método long e não com o método SimpleDateFormat que você usa acima?
AJW
1
Contanto que sejam os milissegundos certos, você pode transmiti-lo como construtor: docs.oracle.com/javase/7/docs/api/java/util/…
rogerdpack
1

Fiz isso de maneira diferente do que todos os outros aqui. Eu sou novo em Java, então talvez minha solução seja ruim.

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

Ainda não tenho certeza de que isso funcione, mas, de qualquer forma, agradeceria qualquer comentário sobre esta solução.

Estou confuso com a afirmação acima de que você pode calcular amanhã ligando para:

c.add(Calendar.DAY_OF_MONTH, 1);

Se você adicionar 1 ao dia do mês e este for o 31º dia, não receberá o 32º dia do mês?

Por que as horas / datas nem todas são baseadas no UTC em Java? Eu acho que fusos horários só devem ser necessários quando usados ​​com E / S, mas internamente sempre devem ser usados ​​no UTC. No entanto, as classes parecem incluir informações de fuso horário, que parecem não apenas um desperdício, mas também propensas a erros de codificação.

Mitch
fonte
2
Oi Mitch. Acho que sua solução funciona, mas parece que o construtor Date está obsoleto. O pessoal do Java reprovou a maioria dos métodos relacionados ao Date originais há um tempo e os substituiu por métodos mais recentes relacionados ao Calendário. Pessoalmente, não vejo como isso é uma melhoria, mas é desaprovado usar métodos obsoletos. Obrigado!
Triste com a depreciação. Parece-me muito mais claro especificar o ano, mês e data, em vez de limpar a hora, o minuto, o segundo e os milissegundos. A limpeza desses recursos depende de milissegundos, sendo a granularidade mais fina da classe Date, enquanto minha solução não. Minha solução também é mais curta e clara. Ser novo em Java me faz realmente apreciar o quão limpo, fácil e eficiente o C ++ é quando se trata de usar datas e horas.
Mitch
@ Mitch Na minha experiência, o idioma mais recente que você está aprendendo é sempre percebido como o mais complicado.
ArtOfWarfare
FYI: essas horríveis e antigas classes de data e hora agora são herdadas, substituídas pelas modernas classes java.time.
Basil Bourque
0

A maneira mais simples com o JodaTime

DateMidnight date = DateMidnight.now();

Javier Sculli
fonte
2
Não. As classes e os métodos relacionados à "meia-noite" no Joda-Time foram preteridos. Eles foram baseados em um conceito defeituoso. O primeiro momento do dia nem sempre é 00:00:00.000. Em vez disso, use o novo withTimeAtStartOfDaymétodo. Atualize para a versão atual 2.4 do Joda-Time e leia as notas de versão. Exemplo:DateTime today = DateTime.now( DateTimeZone.forID( "America/Montreal" ) ).withTimeAtStartOfDay();
Basil Bourque
0

Como um dia é 24 * 60 * 60 * 1000ms, a meia-noite deste dia pode ser calculada como ...

long now = System.currentTimeMillis();
long delta = now % 24 * 60 * 60 * 1000;
long midnight = now - delta;
Date midnightDate = new Date(midnight);`
lshu
fonte
1
Esse código se aplica apenas ao UTC e a nenhum outro fuso horário e ignora anomalias como o horário de verão. Além disso, as soluções de data e hora de roll-your-own são imprudentes, pois esse é um tópico surpreendentemente complicado. Use as excelentes classes java.time.
Basil Bourque
0

Praticamente como as respostas anteriores, mas ninguém mencionou o parâmetro 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
fonte
1
A Calendarclasse problemática foi substituída anos atrás pelas classes java.time , especificamente ZonedDateTime.
Basil Bourque 08/04
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
fonte
Isso funciona apenas para o UTC e falha ao endereçar fusos horários. Além disso, a terrível Dateclasse foi suplantada anos atrás por java.time.Instant. Evite usar Datehoje em dia.
Basil Bourque
0

Usando apache commons ..

//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
fonte
FYI, os terrivelmente problemáticas aulas em tempo data antigas, tais como java.util.Date, java.util.Calendare java.text.SimpleDateFormatestão agora legado , suplantado pelos java.time classes internas em Java 8 e posterior. Consulte o Tutorial da Oracle .
Basil Bourque
@BasilBourque concordou com o Java 8. Mas se o OP estiver usando o Java 7, acho que ainda funcionaria.
Joe4java
Quase toda a funcionalidade java.time está disponível para Java 6 e 7 no projeto ThreeTen-Backport com API praticamente idêntica. Mais adaptado para Android <26 no projeto ThreeTenABP . Portanto, não há necessidade de usar novamente aquelas classes antigas de data e hora miseráveis.
Basil Bourque
-1

Eu sei que este é um post muito antigo. Eu pensei em compartilhar meu conhecimento aqui!

Para a data de hoje à meia-noite com fuso horário exato, você pode usar os seguintes

public static Date getCurrentDateWithMidnightTS(){

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

Onde (1000*60 * 330) está sendo subtraído, isto é, realmente relacionado ao fuso horário, por exemplo, o fuso horário indiano, ou seja, o kolkata difere +5: 30hrs do real. Então, subtraindo isso com a conversão em milissegundos.

Então mude o último número subtraído de acordo com você. Estou criando um produto, ou seja, apenas com base na Índia. Então, usei timestamp específico.

Rajeev
fonte
1
Por que você sugeriria isso em vez da resposta aceita? A rolagem dos valores de data e hora é arriscada em geral. Em particular, esse código é codificado para o deslocamento atual de um único fuso horário para sempre. Não há contabilidade para o horário de verão ou outras anomalias. Vejo apenas desvantagens sem valor agregado.
Basil Bourque 28/11
@ Basil, é claro, eu aceito a resposta e sim, eu mencionei lá pelo valor codificado. Isso é útil apenas no caso de você estar trabalhando em um fuso horário específico.
Rajeev 29/11
-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())));

Mas cuidado que java.sql.Date.toInstant()sempre lançaUnsupportedOperationException .

Via LocalDate para java.util.Date e vice-versa, a conversão mais simples?

Vadzim
fonte
Não é uma boa resposta. Você está misturando o uso do java.time moderno com as antigas classes herdadas que eles substituem. E, especificamente, você usa as classes de data e hora java.sql que devem ser usadas apenas para a troca de dados com um banco de dados cujo driver ainda não foi atualizado para lidar diretamente com as classes java.time, para nunca serem usadas na lógica de negócios. Outro problema é que você ignora a questão crucial do fuso horário.
Basil Bourque
@BasilBourque, obrigado pela crítica. O uso de uma classe herdada que não está marcada como obsoleta para obter outra instância de classe herdada é bastante seguro. A questão do fuso horário é mais importante. Decidi seguir a resposta de riccardo, afinal.
Vadzim
-1

Do modo antigo..

private static Date getDateWithMidnight(){
    long dateInMillis = new Date().getTime();
    return new Date(dateInMillis - dateInMillis%(1000*60*60*24) - TimeZone.getDefault().getOffset(dateInMillis));
}
Prabath
fonte
Essa classe problemática foi substituída anos atrás pela classe java.time.Instant . Não há necessidade de usar Date.
Basil Bourque
Essa Dateclasse está sempre no UTC. Portanto, você está ignorando o problema do fuso horário desejado / esperado. Por exemplo, um novo dia amanhece em Calcutá, na Índia, muitas horas antes do UTC e horas depois do UTC em Montreal Quebec.
Basil Bourque