Joda-Time
En cuanto a agregar una dependencia, me temo que java.util.Date & .Calendar realmente son tan malos que lo primero que hago a cualquier proyecto nuevo es agregar la biblioteca Joda-Time. En Java 8 puede usar el nuevo paquete java.time, inspirado en Joda-Time.
El núcleo de Joda-Time es la DateTimeclase. A diferencia de java.util.Date, entiende su zona horaria asignada ( DateTimeZone). Al convertir de juDate, asigne una zona.
DateTimeZone zone = DateTimeZone.forID( "America/Montreal" );
DateTime dateTimeQuébec = new DateTime( date , zone );
LocalDate
Una forma de verificar si dos fechas y horas aterrizan en la misma fecha es convertirlas en LocalDateobjetos.
Esa conversión depende de la zona horaria asignada. Para comparar LocalDateobjetos, deben haberse convertido con la misma zona.
Aquí hay un pequeño método de utilidad.
static public Boolean sameDate ( DateTime dt1 , DateTime dt2 )
{
LocalDate ld1 = new LocalDate( dt1 );
// LocalDate determination depends on the time zone.
// So be sure the date-time values are adjusted to the same time zone.
LocalDate ld2 = new LocalDate( dt2.withZone( dt1.getZone() ) );
Boolean match = ld1.equals( ld2 );
return match;
}
Mejor sería otro argumento, especificando la zona horaria en lugar de asumir que se debe usar la primera zona horaria del objeto DateTime.
static public Boolean sameDate ( DateTimeZone zone , DateTime dt1 , DateTime dt2 )
{
LocalDate ld1 = new LocalDate( dt1.withZone( zone ) );
// LocalDate determination depends on the time zone.
// So be sure the date-time values are adjusted to the same time zone.
LocalDate ld2 = new LocalDate( dt2.withZone( zone ) );
return ld1.equals( ld2 );
}
Representación de cuerdas
Otro enfoque es crear una representación de cadena de la porción de fecha de cada fecha-hora, luego comparar cadenas.
Nuevamente, la zona horaria asignada es crucial.
DateTimeFormatter formatter = ISODateTimeFormat.date(); // Static method.
String s1 = formatter.print( dateTime1 );
String s2 = formatter.print( dateTime2.withZone( dt1.getZone() ) );
Boolean match = s1.equals( s2 );
return match;
Lapso de tiempo
La solución generalizada es definir un período de tiempo, luego preguntar si el período contiene su objetivo. Este código de ejemplo está en Joda-Time 2.4. Tenga en cuenta que las clases relacionadas con la "medianoche" están en desuso. En su lugar, use el withTimeAtStartOfDaymétodo. Joda-Time ofrece tres clases para representar un lapso de tiempo de varias maneras: intervalo, período y duración.
Usando el enfoque "medio abierto" donde el comienzo del tramo es inclusivo y el final exclusivo.
La zona horaria del objetivo puede ser diferente a la zona horaria del intervalo.
DateTimeZone timeZone = DateTimeZone.forID( "Europe/Paris" );
DateTime target = new DateTime( 2012, 3, 4, 5, 6, 7, timeZone );
DateTime start = DateTime.now( timeZone ).withTimeAtStartOfDay();
DateTime stop = start.plusDays( 1 ).withTimeAtStartOfDay();
Interval interval = new Interval( start, stop );
boolean containsTarget = interval.contains( target );
java.time
Java 8 y posterior viene con el framework java.time . Inspirado por Joda-Time, definido por JSR 310, y ampliado por el proyecto ThreeTen-Extra. Ver tutorial .
Los creadores de Joda-Time nos han ordenado a todos que nos traslademos a java.time tan pronto como sea conveniente. Mientras tanto, Joda-Time continúa como un proyecto mantenido activamente. Pero espere que el trabajo futuro ocurra solo en java.time y ThreeTen-Extra en lugar de Joda-Time.
Para resumir java.time en pocas palabras ... Un Instantes un momento en la línea de tiempo en UTC. Aplique una zona horaria ( ZoneId) para obtener un ZonedDateTimeobjeto. Para mover fuera de la línea de tiempo, para tener una idea vaga indefinida de una fecha-hora, utilice las clases "locales": LocalDateTime, LocalDate, LocalTime.
La lógica discutida en la sección Joda-Time de esta Respuesta se aplica a java.time.
La antigua clase java.util.Date tiene un nuevo toInstantmétodo para la conversión a java.time.
Instant instant = yourJavaUtilDate.toInstant(); // Convert into java.time type.
Determinar una fecha requiere una zona horaria.
ZoneId zoneId = ZoneId.of( "America/Montreal" );
Aplicamos ese objeto de zona horaria Instantpara obtener a ZonedDateTime. De ahí extraemos un valor de solo fecha (a LocalDate) ya que nuestro objetivo es comparar fechas (no horas, minutos, etc.).
ZonedDateTime zdt1 = ZonedDateTime.ofInstant( instant , zoneId );
LocalDate localDate1 = LocalDate.from( zdt1 );
Haga lo mismo con el segundo java.util.Dateobjeto que necesitamos para comparar. Solo usaré el momento actual en su lugar.
ZonedDateTime zdt2 = ZonedDateTime.now( zoneId );
LocalDate localDate2 = LocalDate.from( zdt2 );
Use el isEqualmétodo especial para probar el mismo valor de fecha.
Boolean sameDate = localDate1.isEqual( localDate2 );