Preciso comparar dois Date
s (por exemplo, date1
e date2
) e criar um boolean sameDay
que seja verdadeiro para os dois Date
s compartilhar no mesmo dia e falso se não forem.
Como posso fazer isso? Parece haver um turbilhão de confusão aqui ... e eu gostaria de evitar puxar outras dependências além do JDK, se possível.
para esclarecer: se date1
e date2
compartilhar o mesmo ano, mês e dia, então sameDay
é verdade, caso contrário, é falsa. Sei que isso requer conhecimento de um fuso horário ... seria bom passar um fuso horário, mas posso viver com a GMT ou a hora local, desde que saiba qual é o comportamento.
novamente, para esclarecer:
date1 = 2008 Jun 03 12:56:03
date2 = 2008 Jun 03 12:59:44
=> sameDate = true
date1 = 2009 Jun 03 12:56:03
date2 = 2008 Jun 03 12:59:44
=> sameDate = false
date1 = 2008 Aug 03 12:00:00
date2 = 2008 Jun 03 12:00:00
=> sameDate = false
Respostas:
Observe que "mesmo dia" não é um conceito tão simples quanto parece quando diferentes fusos horários podem estar envolvidos. O código acima calculará para as duas datas o dia em relação ao fuso horário usado pelo computador em que está sendo executado. Se não é isso que você precisa, você deve passar o (s) fuso horário (s) relevante (s) para as
Calendar.getInstance()
chamadas, depois de decidir o que exatamente você quer dizer com "no mesmo dia".E sim, o Joda Time's
LocalDate
tornaria tudo muito mais limpo e fácil (embora as mesmas dificuldades que envolvem fusos horários estariam presentes).fonte
E se:
Você também pode definir o fuso horário como SimpleDateFormat, se necessário.
fonte
SimpleDateFormat
método é realmente mais rápido do que o outro mencionado aqui usandoCalendar
s. Em média, leva metade do tempo comoCalendar
método. (Pelo menos no meu sistema). Parabéns!Eu uso o pacote "apache commons lang" para fazer isso (ou seja, org.apache.commons.lang.time.DateUtils )
fonte
Você pode evitar dependências externas e o desempenho atingido ao usar o Calendário calculando o Número do dia juliano para cada uma das datas e comparando-os:
fonte
Date
s não encapsulam a noção de fuso horário, então não há como corrigir isso de maneira não arbitrária.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.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. Comparar
LocalDate
objetos, eles devem ter sido convertidos com a mesma zona.Aqui está um pequeno método utilitário.
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.
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.
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.
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 umZonedDateTime
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.Determinar uma data requer um fuso horário.
Aplicamos esse objeto de fuso horário ao
Instant
para obter umZonedDateTime
. A partir disso, extraímos um valor somente de data (aLocalDate
), pois nosso objetivo é comparar datas (não horas, minutos etc.).Faça o mesmo com o segundo
java.util.Date
objeto que precisamos para comparação. Vou usar o momento atual.Use o
isEqual
método especial para testar o mesmo valor de data.fonte
LocalDate localDate = LocalDate.fromDateFields(yourJavaUtilDate);
fromDateFields()
na minhaLocalDate
classe .Converta datas para Java 8 java.time.LocalDate, como visto aqui .
fonte
ZoneId.of("America/Phoenix")
ou emZoneId.of("Europe/Budapest")
vez do padrão do sistema.Java 8
Se você estiver usando o Java 8 em seu projeto e comparando
java.sql.Timestamp
, poderá usar aLocalDate
classe:Se você estiver usando
java.util.Date
, dê uma olhada na resposta do Istvan, que é menos ambígua.fonte
date1
edate2
éjava.sql.Timestamp
? De acordo com a pergunta que eles sãoDate
, eu entenderiajava.util.Date
. Além disso, seu código usa a configuração de fuso horário do computador, o que para muitos propósitos será bom; ainda assim, prefiro deixar esse fato explícito no código.java.sql.Timestamp
. Como você disse, geralmente é melhor definir explicitamente o fuso horário.fonte
PARA USUÁRIOS DA ANDROID:
Você pode usar
DateUtils.isToday(dateMilliseconds)
para verificar se a data especificada é o dia atual ou não.Referência da API: https://developer.android.com/reference/android/text/format/DateUtils.html#isToday(long)
fonte
DateUtils.isToday(x.getTime())
(x é uma instância java.util.date) faráalém da solução Binil Thomas
uso
fonte
Para os desenvolvedores do Kotlin, esta é a versão com a comparação da abordagem de strings formatadas:
Não é o melhor caminho, mas é curto e funcional.
fonte
SimpleDateFormat
classe foi substituída anos atrás pelajava.time.DateTimeFormatter
classe moderna definida no JSR 310. Sugerir seu uso em 2019 é um péssimo conselho.você pode aplicar a mesma lógica que a solução SimpleDateFormat sem depender do SimpleDateFormat
fonte