tl; dr
… Analisado… de um String… o fuso horário não está especificado… Quero definir um fuso horário específico
LocalDateTime.parse( "2018-01-23T01:23:45.123456789" ) // Parse string, lacking an offset-from-UTC and lacking a time zone, as a `LocalDateTime`.
.atZone( ZoneId.of( "Africa/Tunis" ) ) // Assign the time zone for which you are certain this date-time was intended. Instantiates a `ZonedDateTime` object.
Sem fuso horário no juDate
Como as outras respostas corretas declararam, um java.util.Date não tem fuso horário † . Representa UTC / GMT (sem deslocamento de fuso horário). Muito confuso porque seu toString
método aplica o fuso horário padrão da JVM ao gerar uma representação de String.
Evite juDate
Por esse e muitos outros motivos, você deve evitar o uso de java.util.Date e .Calendar e java.text.SimpleDateFormat interno. Eles são notoriamente problemáticos.
Em vez disso, use o pacote java.time incluído no Java 8 .
java.time
As classes java.time podem representar um momento na linha do tempo de três maneiras:
- UTC (
Instant
)
- Com um deslocamento (
OffsetDateTime
com ZoneOffset
)
- Com um fuso horário (
ZonedDateTime
com ZoneId
)
Instant
Em java.time , o componente básico é Instant
um momento na linha do tempo no UTC. Use Instant
objetos para grande parte da sua lógica de negócios.
Instant instant = Instant.now();
OffsetDateTime
Aplique um deslocamento do UTC para ajustar o horário do relógio de parede de alguma localidade .
Aplique a ZoneOffset
para obter uma OffsetDateTime
.
ZoneOffset zoneOffset = ZoneOffset.of( "-04:00" );
OffsetDateTime odt = OffsetDateTime.ofInstant( instant , zoneOffset );
ZonedDateTime
Melhor é aplicar um fuso horário , um deslocamento mais as regras para lidar com anomalias, como horário de verão (DST) .
Aplique a ZoneId
a Instant
para obter a ZonedDateTime
. Sempre especifique um nome de fuso horário adequado . Nunca use abreviações de 3 a 4 como EST
ou IST
que não sejam únicas nem padronizadas.
ZoneId zoneId = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = ZonedDateTime.ofInstant( instant , zoneId );
LocalDateTime
Se a sequência de entrada não possuir nenhum indicador de deslocamento ou zona, analise como a LocalDateTime
.
Se você tiver certeza do fuso horário pretendido, atribua a ZoneId
para produzir a ZonedDateTime
. Veja o exemplo de código acima na seção tl; dr na parte superior.
Strings formatadas
Chame o toString
método em qualquer uma dessas três classes para gerar uma String representando o valor de data e hora no formato padrão ISO 8601 . A ZonedDateTime
classe estende o formato padrão acrescentando o nome do fuso horário entre colchetes.
String outputInstant = instant.toString(); // Ex: 2011-12-03T10:15:30Z
String outputOdt = odt.toString(); // Ex: 2007-12-03T10:15:30+01:00
String outputZdt = zdt.toString(); // Ex: 2007-12-03T10:15:30+01:00[Europe/Paris]
Para outros formatos, use a DateTimeFormatter
classe Geralmente, é melhor deixar essa classe gerar formatos localizados usando a linguagem humana esperada do usuário e as normas culturais. Ou você pode especificar um formato específico.
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
, e SimpleDateFormat
.
O projeto Joda-Time , agora em modo de manutenção , aconselha a migração para as classes java.time .
Para saber mais, consulte o Tutorial do Oracle . E procure Stack Overflow para muitos exemplos e explicações. A especificação é JSR 310 .
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 strings, não há necessidade de java.sql.*
classes.
Onde obter as classes java.time?
O projeto ThreeTen-Extra estende o java.time com classes adicionais. Este projeto é um campo de prova para possíveis adições futuras ao java.time. Você pode encontrar algumas classes úteis aqui, como Interval
, YearWeek
, YearQuarter
, e mais .
Joda-Time
Enquanto o Joda-Time ainda é mantido ativamente, seus fabricantes nos disseram para migrar para o java.time o mais rápido possível. Deixo esta seção intacta como referência, mas sugiro usar a java.time
seção acima.
No Joda-Time , um objeto de data e hora ( DateTime
) realmente conhece seu fuso horário atribuído. Isso significa um deslocamento do UTC e as regras e o histórico do horário de verão (DST) do fuso horário e outras anomalias desse tipo.
String input = "2014-01-02T03:04:05";
DateTimeZone timeZone = DateTimeZone.forID( "Asia/Kolkata" );
DateTime dateTimeIndia = new DateTime( input, timeZone );
DateTime dateTimeUtcGmt = dateTimeIndia.withZone( DateTimeZone.UTC );
Chame o toString
método para gerar uma String no formato ISO 8601 .
String output = dateTimeIndia.toString();
O Joda-Time também oferece recursos avançados para gerar todos os tipos de outros formatos de String.
Se necessário, você pode converter de Joda-Time DateTime para um java.util.Date.
Java.util.Date date = dateTimeIndia.toDate();
Pesquise StackOverflow por "joda date" para encontrar muitos mais exemplos, alguns bastante detalhados.
† Na verdade não é um fuso horário incorporado em um java.util.Date, utilizados para algumas funções internas (ver comentários sobre esta resposta). Mas esse fuso horário interno não é exposto como uma propriedade e não pode ser definido. Esse fuso horário interno não é o usado pelo toString
método na geração de uma representação de sequência do valor de data e hora; em vez disso, o fuso horário padrão atual da JVM é aplicado imediatamente. Então, como abreviação, costumamos dizer "juDate não tem fuso horário". Confuso? Sim. Mais uma razão para evitar essas velhas classes cansadas.