Eu tenho um problema ao redefinir horas em Java. Para uma determinada data, desejo definir as horas como 00:00:00.
Este é o meu código:
/**
* Resets milliseconds, seconds, minutes and hours from the provided date
*
* @param date
* @return
*/
public static Date trim(Date date) {
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
calendar.set(Calendar.MILLISECOND, 0);
calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.HOUR, 0);
return calendar.getTime();
}
O problema é que às vezes a hora é 12:00:00
e às vezes é 00:00:00
e quando eu procuro no banco de dados uma entidade que foi salva 07.02.2013 00:00:00
e a hora real da entidade, que está armazenada, 12:00:00
a consulta falha.
Eu sei disso 12:00:00 == 00:00:00
!
Estou usando o AppEngine. Este é um bug do appengine, problema ou algum outro problema? Ou depende de outra coisa?
java
java.util.calendar
Adelin
fonte
fonte
java.util.Date
,java.util.Calendar
ejava.text.SimpleDateFormat
agora são legadas , suplantadas pelas classes java.time construídas em Java 8 e Java 9. Consulte o Tutorial da Oracle .calendar.set(Calendar.HOUR_OF_DAY, 0);
, para meu propósito, funciona bem.Respostas:
Use outra constante em vez de
Calendar.HOUR
, useCalendar.HOUR_OF_DAY
.Calendar.HOUR
usa 0-11 (para uso com AM / PM) eCalendar.HOUR_OF_DAY
usa 0-23.Para citar os Javadocs:
e
Teste ("agora" é atualmente 14h55 de 23 de julho de 2013, horário de verão do Pacífico):
Resultado:
fonte
Calendar.HOUR
não definiria PM como AM, deixando-o como 12:00.java.util.Date
,java.util.Calendar
ejava.text.SimpleDateFormat
agora são legadas , suplantadas pelas classes java.time construídas em Java 8 e Java 9. Consulte o Tutorial da Oracle .java.time
Usando a
java.time
estrutura integrada em Java 8 e posterior. Veja o tutorial .Se você não precisa da hora do dia (hora, minuto, segundo, etc. partes), considere usar a
LocalDate
classe.fonte
LocalDateTime
é exatamente a classe errada a ser usada para isso. Não pode representar um momento, pois carece de qualquer conceito de fuso horário ou deslocamento do UTC. LigarLocalDateTime.now
quase nunca faz sentido. Use em seuZonedDateTime
lugar. Caso contrário, você estará ignorando questões cruciais de fuso horário. Por um lado, algumas datas em algumas zonas não começam às 00:00!Aqui estão algumas funções utilitárias que uso para fazer exatamente isso.
fonte
Mais um modo JAVA 8:
Mas é muito mais útil editar a data que já existe.
fonte
LocalDateTime
não pode representar um momento, pois carece de qualquer conceito de fuso horário ou deslocamento do UTC. LigarLocalDateTime.now
quase nunca faz sentido. Você deveria estar usandoZonedDateTime
.É melhor definir principalmente o fuso horário para o componente DateFormat, como este:
Então você pode obter o tempo "00:00:00" passando 0 milissegundos para o formatador:
ou você pode criar o objeto Date:
ou você pode ter mais possibilidades usando o componente Calendário, mas também deve definir o fuso horário como GMT para a instância do calendário:
fonte
tl; dr
java.time
Você está usando classes terríveis de data e hora que foram suplantadas anos atrás pelas classes java.time modernas definidas no JSR 310.
Date
➙Instant
A
java.util.Date
representa um momento no UTC. Sua substituição éInstant
. Chame os novos métodos de conversão adicionados às classes antigas.Fuso horário
Especifique o fuso horário no qual deseja que a nova hora do dia faça sentido.
Especifique um nome próprio fuso horário no formato
Continent/Region
, comoAmerica/Montreal
,Africa/Casablanca
, ouPacific/Auckland
. Nunca use o 2-4 letras, comoEST
ouIST
como eles são não zonas verdadeiros tempo, não padronizados, e nem mesmo única (!).ZonedDateTime
Aplique o
ZoneId
aoInstant
para obter umZonedDateTime
. Mesmo momento, mesmo ponto na linha do tempo, mas com um relógio de parede diferente.Mudando a hora do dia
Você pediu para alterar a hora do dia. Aplique a
LocalTime
para alterar todas as partes da hora do dia: hora, minuto, segundo, segundo fracionário. Um novoZonedDateTime
é instanciado, com valores baseados no original. As classes java.time usam esse padrão de objetos imutáveis para fornecer segurança de thread .Primeiro momento do dia
Mas você pediu especificamente para 00:00. Então, aparentemente, você quer o primeiro momento do dia. Cuidado: alguns dias em algumas zonas não começam às 00:00:00. Eles podem iniciar em outro horário, como 01:00:00 devido a anomalias como horário de verão (DST).
Deixe java.time determinar o primeiro momento. Extraia a parte apenas da data. Em seguida, passe o fuso horário para obter o primeiro momento.
Ajustar para UTC
Se você precisar voltar ao UTC, extraia um
Instant
.Instant
➙Date
Se você precisar
java.util.Date
interoperar com o código antigo ainda não atualizado para java.time , converta.fonte
Fazer isso poderia ser mais fácil (em Java 8)
fonte
Podemos definir a parte do tempo java.util.Date para 00:00:00 usando a classe LocalDate do Java 8 / Joda-datetime api :
fonte
Se você precisar do formato 00:00:00 em string, deve usar SimpleDateFormat conforme abaixo. Usando "H" em vez de "h".
fonte
Outra maneira de fazer isso seria usar um DateFormat sem segundos:
fonte
Você pode fazer isso com o seguinte:
fonte
Como Java8 adiciona novas funções de data, podemos fazer isso facilmente.
fonte
LocalDateTime
não pode representar um momento, pois carece de qualquer conceito de fuso horário ou deslocamento do UTC. LigarLocalDateTime.now
quase nunca faz sentido. Você deveria estar usandoZonedDateTime
.