java.util.Datenunca é 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 o toString()confunda, que de fato usa uma representação em fuso horário local.
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;
obrigado. é possível converter ZonedDateTime em Date ou em long (ms)?
Marque
7
Embora o código deste respondente funcione tecnicamente, não seria mais apropriado usar em OffsetDateTimevez de ZonedDateTimeconsiderar que estamos trabalhando com um mero deslocamento do UTC em vez de um fuso horário completo?
Basil Bourque de
179
tl; dr
Instant.now()
java.time
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 Instantrepresenta um momento na linha do tempo em UTC com uma resolução de até nanossegundos .
Instant instant =Instant.now();
O toStringmé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 Instantclasse é 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 Instanttem limitações, como nenhuma opção de formatação para gerar strings em formatos alternativos. Para obter mais flexibilidade, converta de Instantpara OffsetDateTime. Especifique um deslocamento do UTC . Em java.time, isso significa um ZoneOffsetobjeto. Aqui, queremos manter o UTC (+00) para que possamos usar a constante conveniente ZoneOffset.UTC.
Agora com um OffsetDateTimeobjeto em mãos, você pode usar DateTimeFormatterpara criar objetos String com texto em formatos alternativos. Procure no Stack Overflow muitos exemplos de uso DateTimeFormatter.
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 15vez de 19horas. Instante ZonedDateTimeambos representam o mesmo momento simultâneo, visto apenas por duas lentes diferentes.
ZoneId z =ZoneId.of("America/Montreal");ZonedDateTime zdt = instant.atZone( z );
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 .
Versões posteriores do Android (26+) agrupam implementações das classes java.time .
Para o Android anterior (<26), um processo conhecido como API desugaring traz um subconjunto da funcionalidade java.time não originalmente integrada ao Android.
Agradeço por dizer que o horário de verão não faz sentido :-)
prash
então, se o DST não existisse ZonedDateTime, não seria necessário, já que todos ZoneIdseriam mapeados para um ZoneOffsetque poderíamos apenas usar OffsetDateTime?
Wilmol
1
@wilmol Não. O horário de verão (DST) é apenas um dos muitos motivos pelos quais os políticos optam por redefinir os limites e compensações dos fusos horários dentro desses fusos horários. Recentemente, a Coreia do Norte mudou seu relógio em meia hora para sincronizar com a Coreia do Sul por razões diplomáticas. Na guerra, os invasores / ocupantes podem alterar o deslocamento para coincidir com o do país de origem. Atualmente, existe uma nova moda em que os governos estão optando por interromper as alterações do horário de verão, mas permanecem permanentemente no horário de verão, em vez de reverter ao horário padrão anterior. Sempre planeje o deslocamento de cada mudança de zona ou seu aplicativo irá eventualmente quebrar.
Basil Bourque
1
Resposta fantástica! Eu realmente aprecio o tempo que você dedicou a isso. :)
drognisep
ZoneId.of ("América / Montreal"); por que alguém inventaria tal coisa no jdk? é feio, nojento, não dizer se há algo errado até o tempo de execução, quem pode se lembrar de todo aquele código rígido? por que não implementá-lo na classe ENUM?
workplaylifecycle
4
Em java8, eu usaria a Instantclasse 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"));
Não, nãoInstant 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. InstantInstant
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.Respostas:
Com o Java 8 você pode escrever:
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:
fonte
OffsetDateTime
vez deZonedDateTime
considerar que estamos trabalhando com um mero deslocamento do UTC em vez de um fuso horário completo?tl; dr
java.time
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 .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 .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 deInstant
paraOffsetDateTime
. Especifique um deslocamento do UTC . Em java.time, isso significa umZoneOffset
objeto. Aqui, queremos manter o UTC (+00) para que possamos usar a constante convenienteZoneOffset.UTC
.Ou pule a
Instant
aula.Agora com um
OffsetDateTime
objeto em mãos, você pode usarDateTimeFormatter
para criar objetos String com texto em formatos alternativos. Procure no Stack Overflow muitos exemplos de usoDateTimeFormatter
.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, em15
vez de19
horas.Instant
eZonedDateTime
ambos representam o mesmo momento simultâneo, visto apenas por duas lentes diferentes.Convertendo
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 )
ejava.util.Date::toInstant
.E indo na outra direção.
Da mesma forma, procure novos métodos adicionados a
GregorianCalendar
(subclasse deCalendar
) para conversão de e parajava.time.ZonedDateTime
.Sobre java.time
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
, eSimpleDateFormat
.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?
fonte
ZonedDateTime
, não seria necessário, já que todosZoneId
seriam mapeados para umZoneOffset
que poderíamos apenas usarOffsetDateTime
?Em java8, eu usaria a
Instant
classe que já está em UTC e é conveniente para trabalhar.Como alternativa, você pode usar o seguinte:
De volta a
Instant
fonte
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
fonte
Solução de 1 linha em Java 8:
fonte