¿Cómo crear un objeto Java Date de medianoche hoy y medianoche mañana?

178

En mi código necesito encontrar todas mis cosas que sucedieron hoy. Así que necesito comparar las fechas desde hoy a las 00:00 a.m. (medianoche de esta mañana) hasta las 12:00 p.m. (medianoche de esta noche).

Lo sé ...

Date today = new Date(); 

... me atrapa ahora mismo. Y ...

Date beginning = new Date(0);

... me da cero tiempo el 1 de enero de 1970. Pero, ¿cuál es una manera fácil de obtener cero tiempo hoy y cero tiempo mañana?

ACTUALIZAR; Hice esto, pero seguramente hay una manera más 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();
RUMANIA_ingeniero
fuente
3
En mi opinión, Joda Time es más fácil, mira el final de mi respuesta. Si desea usar java.util.Date/Calendar, debe hacerlo de esta manera, no hay una manera más fácil de hacerlo.
timaschew
RE: timaschew comenta para usar Joda-Time, sabe que el proyecto Joda-Time ahora está en modo de mantenimiento y aconseja la migración a las clases java.time.
Basil Bourque
1
Para su información, las antiguas clases de fecha y hora terriblemente problemáticas como java.util.Date, java.util.Calendary java.text.SimpleDateFormatahora son heredadas , suplantadas por las clases java.time integradas en Java 8 y posteriores. Ver Tutorial de Oracle .
Basil Bourque
2
Rara vez se ven tantas respuestas defectuosas a una pregunta como a esta. Recomiendo la respuesta de Basil Bourque , es correcta y está bien informada.
Ole VV

Respuestas:

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

Si está utilizando un JDK <8, recomiendo Joda Time , porque la API es realmente buena:

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

Dado que la versión 2.3 de Joda Time DateMidnightestá en desuso , use esto:

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

Pase una zona horaria si no desea la zona horaria predeterminada actual de la JVM.

DateTimeZone timeZone = DateTimeZone.forID("America/Montreal");
DateTime today = new DateTime(timeZone).withTimeAtStartOfDay(); // Pass time zone to constructor.
timaschew
fuente
Gracias por la ayuda, acababa de actualizar mi pregunta original con cómo lo estaba haciendo actualmente. Gracias por la sugerencia.
3
A partir de JodaTime 2.3, toDateMidnightestá en desuso. Vea esta respuesta para más detalles: stackoverflow.com/a/19048833/363573
Stephan
agregó una solución para JDK 8
timaschew
1
@timaschew Aunque generalmente es correcto, sugiero hacer el java.time usando un valor de fecha y hora zonificado ( ZonedDateTime) como lo hizo en la sección Joda-Time. Los Local…tipos no tienen información de zona horaria; ese es su propósito completo, no perder / ignorar todos los detalles de compensación y zona horaria. Especialmente cuando la Pregunta habla sobre el uso de estos valores para la comparación (¿quizás consultas de bases de datos?), Es probable que un valor de fecha y hora dividido en zonas sea más útil.
Basil Bourque
1
@Amalgovinus Asegúrese de configurar Calendar.HOUR_OF_DAY, no Calendar.HOUR.
Oswald
43

En aras de la exhaustividad, si está utilizando Java 8 , también puede utilizar el truncatedTométodo de la Instantclase para obtener la medianoche en UTC .

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

Como está escrito en el Javadoc

Por ejemplo, truncar con la unidad MINUTOS se redondeará al minuto más cercano, configurando los segundos y nanosegundos a cero.

Espero eso ayude.

riccardo.cardin
fuente
1
Gracias por la pista. Obtener la medianoche en la zona horaria especificada se vuelve más larga:Date.from(date.toInstant().atZone(ZoneId.systemDefault()).truncatedTo(ChronoUnit.DAYS).toInstant())
Vadzim
44
Cuidado con la diferencia entre truncatedToyatStartOfDay .
Vadzim
33

La forma más fácil de encontrar una medianoche:

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

Día siguiente:

Date date = new Date(date.getTime() + 24 * 60 * 60 * 1000);
Andrei Volgin
fuente
Ejecuté ese código y obtuve: Medianoche: Jue Nov 01 19:00:00 CDT 2012
Dave
3
Si hizo algo como System.out.print (fecha), el sistema convirtió la instancia de fecha en la zona horaria del sistema (CDT). 7pm en CDT es medianoche en GMT. Si necesita una medianoche en una zona horaria seleccionada, debe agregar el desplazamiento de esta zona horaria, teniendo en cuenta el horario de verano.
Andrei Volgin
@Bouncner lo es. Hay muchas horas diferentes de 'medianoche' en la Tierra, independientemente del método que utilice, pero solo hay una medianoche de Java.
Andrei Volgin
2
@Andrei Volgin No sabía que hay una "medianoche de Java". ;) Lo que quería decir es que esta solución realmente no ayuda al creador del tema. Una solución de calendario evita los segundos cálculos feos y se ocupa de las zonas horarias (y especialmente los horarios de verano, etc.) cuando se usa correctamente. No veo eso en tu solución.
Bouncner
Hola @AndreiVolgin, obtuve con Date date = new Date (time + TimeZone.getDefault (). GetRawOffset () - time% (24 * 60 * 60 * 1000));
jrey
28

Recuerde, Dateno se usa para representar fechas (!). Para representar la fecha necesitas un calendario. Esta:

Calendar c = new GregorianCalendar();

creará una Calendarinstancia que represente la fecha actual en su zona horaria actual. Ahora lo que necesita es truncar cada campo debajo del día (hora, minuto, segundo y milisegundo) configurándolo en 0. Ahora tienes una medianoche hoy.

Ahora para llegar a la medianoche del día siguiente, debe agregar un día:

c.add(Calendar.DAY_OF_MONTH, 1);

Tenga en cuenta que agregar 86400segundos o 24 horas es incorrecto debido al horario de verano que puede ocurrir mientras tanto.

ACTUALIZACIÓN: Sin embargo, mi forma favorita de tratar este problema es usar la clase DateUtils de Commons Lang :

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

Utiliza Calendardetrás de escena ...

Tomasz Nurkiewicz
fuente
15
Gracias por la ayuda. "La fecha no se usa para representar fechas" - eso es genial, ¿no? ;)
@RobertHume Para ser justos, Date ha existido desde el primer lanzamiento de Java. La mayoría de las cosas de esa época son ... menos que perfectamente pensadas. Sobre todo porque Java fue uno de los primeros en probar el tipo de cosas que estaba tratando, y no había mucho de un acuerdo sobre un estándar de cómo hacerlo.
Financia la demanda de Mónica el
14

estos métodos te ayudarán

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

y

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

A partir de JodaTime 2.3, el toDateMidnight()está en desuso.

De la actualización de 2.2 a 2.3

    Desaprobaciones desde 2.2
    ----------------------
    - DateMidnight [# 41]
     Esta clase tiene un concepto defectuoso
     La hora de la medianoche ocasionalmente no ocurre en algunas zonas horarias.
     Esto es el resultado de un horario de verano de 00:00 a 01:00
     DateMidnight es esencialmente un DateTime con un tiempo bloqueado hasta la medianoche
     Tal concepto es generalmente más pobre de usar, dado LocalDate
     Reemplazar DateMidnight con LocalDate
     O reemplácelo con DateTime, quizás usando el método withTimeAtStartOfDay ()

Aquí hay un código de muestra sin toDateMidnight()método.

Código

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

Salida ( puede ser diferente dependiendo de su zona horaria local )

2013-09-28 00:00:00
Stephan
fuente
2
Excelente respuesta Me gustaría agregar pasar una DateTimeZoneinstancia a ese DateTimeconstructor para enfatizar la importancia de especificar una zona horaria en lugar de inadvertidamente dependiendo del valor predeterminado:DateTimeZone timeZone = DateTimeZone.forID( "Europe/Paris" );
Basil Bourque
9

Otras respuestas son correctas, especialmente la respuesta java.time de arganzheng . Como algunos mencionaron, debe evitar las antiguas clases java.util.Date/.Calendar ya que están mal diseñadas, son confusas y problemáticas. Han sido suplantados por las clases java.time.

Permítanme agregar notas sobre la estrategia para manejar la medianoche y el lapso de tiempo .

Medio abierto

En el trabajo de fecha y hora, los períodos de tiempo a menudo se definen utilizando el enfoque "medio abierto". En este enfoque, el comienzo es inclusivo, mientras que el final es exclusivo . Esto resuelve los problemas y, si se usa de manera sistemática, facilita mucho el razonamiento sobre el manejo de la fecha y hora.

Un problema resuelto es definir el final del día. ¿Es el último momento del día 23:59:59.999( milisegundos )? Tal vez, en la clase java.util.Date (desde el primer Java; problemático, ¡evite esta clase!) Y en la exitosa biblioteca Joda-Time . Pero en otro software, como una base de datos como Postgres, el último momento será 23:59:59.999999( microsegundos ). Pero en otro software como el framework java.time (integrado en Java 8 y posterior, sucesor de Joda-Time) y en alguna base de datos como la Base de datos H2 , el último momento podría ser 23:59.59.999999999( nanosegundos ). En lugar de partir los pelos, piense solo en el primer momento, no en el último.

En Half-Open, un día transcurre desde el primer momento de un día y sube, pero no incluye el primer momento del día siguiente. Entonces, en lugar de pensar así:

... desde hoy a las 00:00 a.m. (medianoche de esta mañana) hasta las 12:00 p.m. (medianoche de esta noche).

... piensa así ...

desde el primer momento de hoy hasta el primer momento de mañana:
(> = 00:00:00.0hoy Y < 00:00:00.0mañana)

En el trabajo de base de datos, este enfoque significa no usar el BETWEENoperador en SQL.

Comienzo del día

Además, el primer momento del día no siempre es la hora del día 00:00:00.0. El horario de verano (DST) en algunas zonas horarias, y posiblemente otras anomalías, puede significar que una hora diferente comienza el día.

Así que deje que los java.time clases hacen el trabajo de determinar el comienzo de un día con una llamada a LocalDate::atStartOfDay( ZoneId ). Por lo tanto, debemos desviarnos LocalDatey regresar a ellos, ZonedDateTimecomo puede ver en este código de ejemplo.

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

Tenga en cuenta el paso de lo opcional ZoneId. Si se omite, la zona horaria predeterminada actual de su JVM se aplica implícitamente. Mejor ser explícito.

La zona horaria es crucial para el trabajo de fecha y hora. La pregunta y algunas otras respuestas son potencialmente defectuosas porque no manejan conscientemente la zona horaria.

Convertir

Si debe usar java.util.Date o .Calendar, busque nuevos métodos de conversión agregados a esas clases antiguas.

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

Lapso de tiempo

Por cierto, si está haciendo mucho trabajo con períodos de tiempo, eche un vistazo a:

  • Duration
  • Period
  • Interval
    La Intervalclase se encuentra en el proyecto ThreeTen-Extra , una extensión del marco java.time. Este proyecto es el campo de pruebas para posibles adiciones futuras a java.time.
    Interval todayMontreal = Interval.of( todayStart.toInstant() , tomorrowStart.toInstant() );

Sobre java.time

El marco java.time está integrado en Java 8 y versiones posteriores. Estas clases suplantar la vieja problemáticos heredados clases de fecha y hora como java.util.Date, Calendar, y SimpleDateFormat.

El proyecto Joda-Time , ahora en modo de mantenimiento , aconseja la migración a las clases java.time .

Para obtener más información, consulte el Tutorial de Oracle . Y busque Stack Overflow para obtener muchos ejemplos y explicaciones. La especificación es JSR 310 .

Puede intercambiar objetos java.time directamente con su base de datos. Utilice un controlador JDBC compatible con JDBC 4.2 o posterior. No hay necesidad de cadenas, no hay necesidad de java.sql.*clases.

¿Dónde obtener las clases java.time?

El proyecto ThreeTen-Extra extiende java.time con clases adicionales. Este proyecto es un campo de pruebas para posibles adiciones futuras a java.time. Usted puede encontrar algunas clases útiles aquí, como Interval, YearWeek, YearQuarter, y más .

Albahaca Bourque
fuente
6

java.time

Si está utilizando Java 8 y versiones posteriores, puede probar el paquete java.time ( Tutorial ):

LocalDate tomorrow = LocalDate.now().plusDays(1);
Date endDate = Date.from(tomorrow.atStartOfDay(ZoneId.systemDefault()).toInstant());
arganzheng
fuente
2
Buena respuesta. Sugeriría especificar la zona horaria deseada / esperada. La zona horaria predeterminada actual de la JVM puede variar según la configuración del sistema operativo, el cambio de computadoras o cualquier aplicación en cualquier subproceso de la JVM que cambie la configuración predeterminada en cualquier momento durante el tiempo de ejecución.
Basil Bourque
4

Esto parece ser una opción:

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

para agregarle un día

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

o

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

Tengo el presentimiento de que este último se prefiere en caso de que algo extraño como el horario de verano provoque que agregar 24 horas no sea suficiente (consulte https://stackoverflow.com/a/4336131/32453 y sus otras respuestas).

rogerdpack
fuente
Tengo una fecha y hora del día representadas como largas en mi base de datos sqlite. Necesito tener un largo para el comienzo del día siguiente. ¿Puedo seguir usando un objeto Date con mi método largo en lugar de con el método SimpleDateFormat que usas arriba?
AJW
1
Mientras sea el milisegundo correcto, puede pasarlo como constructor: docs.oracle.com/javase/7/docs/api/java/util/…
rogerdpack
1

Hice esto de manera diferente a todos los demás aquí. Soy nuevo en Java, así que tal vez mi solución es pobre.

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

No estoy seguro de que esto funcione todavía, pero de cualquier manera, agradecería cualquier comentario sobre esta solución.

Estoy confundido por la declaración anterior de que puedes calcular mañana llamando:

c.add(Calendar.DAY_OF_MONTH, 1);

Si agrega 1 al día del mes y es el día 31, ¿no obtiene el día 32 del mes?

¿Por qué las horas / fechas no están todas basadas en UTC en Java? Creo que las zonas horarias solo deberían ser necesarias cuando se usan con E / S, pero internamente siempre deberían usarse en UTC. Sin embargo, las clases parecen incluir información de zona horaria que no solo es un desperdicio, sino que es propensa a errores de codificación.

Mitch
fuente
2
Hola Mitch Creo que su solución funciona, pero parece que el constructor de Date está en desuso. La gente de Java desaprobó la mayoría de los métodos originales relacionados con Date hace un tiempo y los reemplazó con métodos más nuevos relacionados con Calendar. Personalmente no veo cómo es una mejora, pero está mal visto el uso de métodos obsoletos. ¡Gracias!
Triste por la depreciación. Me parece mucho más claro especificar el año, mes y fecha en lugar de borrar la hora, minuto, segundo y milisegundos. Borrar esto depende de que los milisegundos sean la mejor granularidad de la clase Fecha, mientras que mi solución no lo hace. Mi solución también es más corta y clara. Ser nuevo en Java me hace apreciar realmente cuán limpio, fácil y eficiente es C ++ cuando se trata de usar fechas y horas.
Mitch
@Mitch En mi experiencia, el idioma más reciente que estás aprendiendo siempre se percibe como el más complicado.
ArtOfWarfare
FYI: estas sangrientas y viejas clases de fecha y hora ahora son heredadas, suplantadas por las modernas clases java.time.
Basil Bourque
0

La forma más sencilla con JodaTime

DateMidnight date = DateMidnight.now();

Javier Sculli
fuente
2
No. Las clases y métodos relacionados con la "medianoche" en Joda-Time han quedado en desuso. Se basaron en un concepto defectuoso. El primer momento del día no es siempre 00:00:00.000. En su lugar, use el nuevo withTimeAtStartOfDaymétodo. Actualice a la versión actual 2.4 de Joda-Time y lea las notas de la versión. Ejemplo:DateTime today = DateTime.now( DateTimeZone.forID( "America/Montreal" ) ).withTimeAtStartOfDay();
Basil Bourque
0

Debido a que un día es 24 * 60 * 60 * 1000ms, la medianoche de este día se puede calcular como ...

long now = System.currentTimeMillis();
long delta = now % 24 * 60 * 60 * 1000;
long midnight = now - delta;
Date midnightDate = new Date(midnight);`
lshu
fuente
1
Este código solo se aplica a UTC y a ninguna otra zona horaria, e ignora anomalías como el horario de verano. Además, las soluciones de rodar su propia fecha y hora no son sabias, ya que este es un tema sorprendentemente complicado. Utilice las excelentes clases java.time en su lugar.
Basil Bourque
0

Más o menos como las respuestas anteriores, pero nadie mencionó el 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
fuente
1
La Calendarclase problemática fue suplantada hace años por las clases java.time , específicamente ZonedDateTime.
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
fuente
Esto solo funciona para UTC y no aborda las zonas horarias. Además, la Dateclase terrible fue suplantada hace años por java.time.Instant. Evite usar Datehoy en día.
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
fuente
Para su información, las antiguas clases de fecha y hora terriblemente problemáticas como java.util.Date, java.util.Calendary java.text.SimpleDateFormatahora son heredadas , suplantadas por las clases java.time integradas en Java 8 y posteriores. Ver Tutorial de Oracle .
Basil Bourque
@BasilBourque acordó para Java 8. Pero si OP está utilizando Java 7, supongo que aún funcionaría.
joe4java
Casi toda la funcionalidad java.time está disponible para Java 6 y 7 en el proyecto ThreeTen-Backport con una API prácticamente idéntica. Más adaptado para Android <26 en el proyecto ThreeTenABP . Por lo tanto, no es necesario volver a usar esas viejas clases de fecha y hora.
Basil Bourque
-1

Sé que esta es una publicación muy antigua. ¡Pensé compartir mi conocimiento aquí!

Para la fecha a media noche de hoy con la zona horaria exacta, puede usar los siguientes

public static Date getCurrentDateWithMidnightTS(){

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

Dónde (1000*60 * 330)se resta, es decir, en realidad está relacionado con la zona horaria, por ejemplo, la zona horaria india, es decir, kolkata difiere +5: 30hrs de la real. Restando eso con la conversión a milisegundos.

Entonces cambie el último número restado de acuerdo con usted. Estoy creando un producto, es decir, solo con sede en India, así que solo utilicé una marca de tiempo específica.

Rajeev
fuente
1
¿Por qué sugerirías esto en lugar de la respuesta aceptada? Rodar sus valores de fecha y hora es arriesgado en general. En particular, este código está codificado para el desplazamiento actual de una sola zona horaria para siempre. No se tiene en cuenta el horario de verano u otras anomalías. Solo veo inconvenientes sin valor agregado.
Basil Bourque
@Basil, por supuesto, acepto la respuesta y sí, mencioné allí por valor codificado. Esto es útil solo en caso de que esté trabajando en una zona horaria específica.
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())));

Pero cuidado que java.sql.Date.toInstant()siempre tira UnsupportedOperationException.

¿Via LocalDate a java.util.Date y viceversa, la conversión más simple?

Vadzim
fuente
No es una buena respuesta. Está mezclando el uso del java.time moderno con las antiguas clases heredadas que suplantan. Y específicamente usa las clases de fecha y hora java.sql que solo deben usarse para intercambiar datos con una base de datos cuyo controlador aún no se ha actualizado para tratar directamente con las clases java.time, que nunca se usarán para la lógica empresarial. Otro problema es que ignoras el tema crucial de la zona horaria.
Basil Bourque
@BasilBourque, gracias por la crítica. Usar una clase heredada que no está marcada como obsoleta para obtener otra instancia de clase heredada es bastante seguro. El problema de la zona horaria es más importante. Decidí seguir con la respuesta de riccardo después de todo.
Vadzim
-1

De forma anticuada..

private static Date getDateWithMidnight(){
    long dateInMillis = new Date().getTime();
    return new Date(dateInMillis - dateInMillis%(1000*60*60*24) - TimeZone.getDefault().getOffset(dateInMillis));
}
Prabath
fuente
Esa clase problemática fue suplantada hace años por la clase java.time.Instant . No es necesario usarlo nunca Date.
Basil Bourque
Esa Dateclase siempre está en UTC. Por lo tanto, está ignorando el problema de la zona horaria deseada / esperada. Por ejemplo, un nuevo día amanece en Kolkata India muchas horas antes que en UTC, y horas más tarde que UTC en Montreal Québec.
Basil Bourque