Tenho problemas com a classe Date em Java. A classe de data retorna a data da máquina local, mas eu preciso de UTC-0.
Eu pesquisei e encontrei uma ótima solução para JavaScript, mas para Java nada útil.
Como obter a data UTC + 0 no Java 8?
Tenho problemas com a classe Date em Java. A classe de data retorna a data da máquina local, mas eu preciso de UTC-0.
Eu pesquisei e encontrei uma ótima solução para JavaScript, mas para Java nada útil.
Como obter a data UTC + 0 no Java 8?
Respostas:
Com o Java 8 você pode escrever:
OffsetDateTime utc = OffsetDateTime.now(ZoneOffset.UTC);
Para responder ao seu comentário, você pode convertê-lo em uma data (a menos que dependa de um código legado, não vejo nenhuma razão para isso) ou em milis desde as épocas:
Date date = Date.from(utc.toInstant());
long epochMillis = utc.toEpochSecond() * 1000;
OffsetDateTime
vez de ZonedDateTime
considerar que estamos trabalhando com um mero deslocamento do UTC em vez de um fuso horário completo?
Instant.now()
As antigas classes problemáticas de data e hora empacotadas com as primeiras versões do Java foram suplantadas pelas classes java.time construídas no Java 8 e posterior. Veja o tutorial Oracle . Muitas das funcionalidades foram adaptadas para Java 6 e 7 no ThreeTen-Backport e posteriormente adaptadas para Android no ThreeTenABP .
Instant
Um Instant
representa um momento na linha do tempo em UTC com uma resolução de até nanossegundos .
Instant instant = Instant.now();
O toString
método gera um objeto String com texto que representa o valor de data e hora usando um dos formatos padrão ISO 8601 .
String output = instant.toString();
2016-06-27T19: 15: 25.864Z
A Instant
classe é uma classe de bloco de construção básico em java.time. Esta deve ser sua aula preferida ao lidar com data e hora, pois geralmente a prática recomendada é rastrear, armazenar e trocar valores de data e hora em UTC.
OffsetDateTime
Mas Instant
tem limitações, como nenhuma opção de formatação para gerar strings em formatos alternativos. Para obter mais flexibilidade, converta de Instant
para OffsetDateTime
. Especifique um deslocamento do UTC . Em java.time, isso significa um ZoneOffset
objeto. Aqui, queremos manter o UTC (+00) para que possamos usar a constante conveniente ZoneOffset.UTC
.
OffsetDateTime odt = instant.atOffset( ZoneOffset.UTC );
2016-06-27T19: 15: 25.864Z
Ou pule a Instant
aula.
OffsetDateTime.now( ZoneOffset.UTC )
Agora com um OffsetDateTime
objeto em mãos, você pode usar DateTimeFormatter
para criar objetos String com texto em formatos alternativos. Procure no Stack Overflow muitos exemplos de uso DateTimeFormatter
.
ZonedDateTime
Quando você deseja exibir a hora do relógio para algum fuso horário específico, aplique um ZoneId
para obter umZonedDateTime
.
Neste exemplo, aplicamos o fuso horário de Montreal. No verão, sob o absurdo do horário de verão (DST) , a zona tem um deslocamento de -04:00
. Portanto, observe como a hora do dia é quatro horas mais cedo na saída, em 15
vez de 19
horas. Instant
e ZonedDateTime
ambos representam o mesmo momento simultâneo, visto apenas por duas lentes diferentes.
ZoneId z = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = instant.atZone( z );
2016-06-27T15: 15: 25.864-04: 00 [America / Montreal]
Embora você deva evitar as classes de data e hora antigas, se necessário, você pode converter usando novos métodos adicionados às classes antigas. Aqui usamos java.util.Date.from( Instant )
e java.util.Date::toInstant
.
java.util.Date utilDate = java.util.Date.from( instant );
E indo na outra direção.
Instant instant= utilDate.toInstant();
Da mesma forma, procure novos métodos adicionados a GregorianCalendar
(subclasse de Calendar
) para conversão de e para java.time.ZonedDateTime
.
A estrutura java.time é integrada ao Java 8 e posterior. Essas classes suplantar os velhos problemáticos legados aulas de data e hora, como java.util.Date
, Calendar
, e SimpleDateFormat
.
Para saber mais, consulte o tutorial Oracle . E pesquise no Stack Overflow para muitos exemplos e explicações. A especificação é JSR 310 .
O projeto Joda-Time , agora em modo de manutenção , aconselha a migração para as classes java.time .
Você pode trocar objetos java.time diretamente com seu banco de dados. Use um driver JDBC compatível com JDBC 4.2 ou posterior. Não há necessidade de cordas, não há necessidade de java.sql.*
classes. Hibernate 5 e JPA 2.2 suportam java.time .
Onde obter as classes java.time?
ZonedDateTime
, não seria necessário, já que todos ZoneId
seriam mapeados para um ZoneOffset
que poderíamos apenas usar OffsetDateTime
?
Em java8, eu usaria a Instant
classe que já está em UTC e é conveniente para trabalhar.
import java.time.Instant;
Instant ins = Instant.now();
long ts = ins.toEpochMilli();
Instant ins2 = Instant.ofEpochMilli(ts)
Como alternativa, você pode usar o seguinte:
import java.time.*;
Instant ins = Instant.now();
OffsetDateTime odt = ins.atOffset(ZoneOffset.UTC);
ZonedDateTime zdt = ins.atZone(ZoneId.of("UTC"));
De volta a Instant
Instant ins4 = Instant.from(odt);
Instant
está no horário local. Um , por definição, está em UTC. Portanto, não há necessidade das maquinações vistas nesta Resposta tentando entrar no UTC; o já está em UTC. Veja minha resposta para mais informações e um código muito mais simples. Instant
Instant
No Java8, você usa a nova API Time e converte um Instant em um ZonedDateTime usando o UTC TimeZone
Solução de 1 linha em Java 8:
public Date getCurrentUtcTime() {
return Date.from(Instant.now());
}
java.util.Date
nunca é uma data de máquina local. É sempre definido como milissegundos decorridos desde 01/01/1970 em relação ao UTC + 00: 00. Talvez o comportamento de seu método otoString()
confunda, que de fato usa uma representação em fuso horário local.