Joda-Time
Quanto à adição de uma dependência, receio que o java.util.Date e o .Calendar sejam tão ruins que a primeira coisa que faço em qualquer novo projeto é adicionar a biblioteca Joda-Time. No Java 8, você pode usar o novo pacote java.time, inspirado no Joda-Time.
O núcleo do Joda-Time é a DateTime
classe. Ao contrário do java.util.Date, ele entende o fuso horário atribuído ( DateTimeZone
). Ao converter a partir de juDate, atribua uma zona.
DateTimeZone zone = DateTimeZone.forID( "America/Montreal" );
DateTime dateTimeQuébec = new DateTime( date , zone );
LocalDate
Uma maneira de verificar se duas datas estão na mesma data é converter para LocalDate
objetos.
Essa conversão depende do fuso horário atribuído. CompararLocalDate
objetos, eles devem ter sido convertidos com a mesma zona.
Aqui está um pequeno método utilitário.
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;
}
Melhor seria outro argumento, especificando o fuso horário em vez de assumir que o fuso horário do primeiro objeto DateTime deve ser usado.
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 );
}
Representação de String
Outra abordagem é criar uma representação de string da parte da data de cada data e hora e comparar as strings.
Novamente, o fuso horário atribuído é 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;
Período de tempo
A solução generalizada é definir um período de tempo e perguntar se o período contém seu destino. Este código de exemplo está no Joda-Time 2.4. Observe que as classes relacionadas à "meia-noite" foram preteridas. Em vez disso, use o withTimeAtStartOfDay
método O Joda-Time oferece três classes para representar um período de tempo de várias maneiras: Intervalo, Período e Duração.
Usando a abordagem "semi-aberta", onde o início do período é inclusivo e o final exclusivo.
O fuso horário do destino pode ser diferente do fuso horário do 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
O Java 8 e posterior vem com a estrutura java.time . Inspirado no Joda-Time, definido pelo JSR 310, e estendido pelo projeto ThreeTen-Extra. Veja o tutorial .
Os criadores do Joda-Time nos instruíram a mudar para java.time o mais rápido possível. Enquanto isso, o Joda-Time continua como um projeto mantido ativamente. Mas espere que o trabalho futuro ocorra apenas em java.time e ThreeTen-Extra, em vez de Joda-Time.
Para resumir java.time em poucas palavras… Um Instant
é um momento na linha do tempo no UTC. Aplique um fuso horário ( ZoneId
) para obter um ZonedDateTime
objeto. Para mover para fora da linha do tempo, para obter a idéia indefinida vaga de uma data-hora, use as classes "locais": LocalDateTime
, LocalDate
,LocalTime
.
A lógica discutida na seção Joda-Time desta resposta se aplica a java.time.
A antiga classe java.util.Date possui um novo toInstant
método de conversão para java.time.
Instant instant = yourJavaUtilDate.toInstant(); // Convert into java.time type.
Determinar uma data requer um fuso horário.
ZoneId zoneId = ZoneId.of( "America/Montreal" );
Aplicamos esse objeto de fuso horário ao Instant
para obter um ZonedDateTime
. A partir disso, extraímos um valor somente de data (a LocalDate
), pois nosso objetivo é comparar datas (não horas, minutos etc.).
ZonedDateTime zdt1 = ZonedDateTime.ofInstant( instant , zoneId );
LocalDate localDate1 = LocalDate.from( zdt1 );
Faça o mesmo com o segundo java.util.Date
objeto que precisamos para comparação. Vou usar o momento atual.
ZonedDateTime zdt2 = ZonedDateTime.now( zoneId );
LocalDate localDate2 = LocalDate.from( zdt2 );
Use o isEqual
método especial para testar o mesmo valor de data.
Boolean sameDate = localDate1.isEqual( localDate2 );