tl; dr
myUtilDate.toInstant() // Convert `java.util.Date` to `Instant`.
.atOffset( ZoneOffset.UTC ) // Transform `Instant` to `OffsetDateTime`.
.format( DateTimeFormatter.ISO_LOCAL_DATE_TIME ) // Generate a String.
.replace( "T" , " " ) // Put a SPACE in the middle.
2014-11-14 14:05:09
java.time
A maneira moderna é com as classes java.time que agora substituem as antigas classes problemáticas de data e hora herdadas.
Primeiro converta seu java.util.Date
para um Instant
. A Instant
classe representa um momento na linha do tempo no UTC com uma resolução de nanossegundos (até nove (9) dígitos de uma fração decimal).
Conversões de / para java.time são executadas por novos métodos adicionados às classes antigas.
Instant instant = myUtilDate.toInstant();
Tanto o seu java.util.Date
como o java.time.Instant
estão no UTC . Se você deseja ver a data e a hora como UTC, que assim seja. Chame toString
para gerar uma String no formato ISO 8601 padrão.
String output = instant.toString();
2014-11-14T14: 05: 09Z
Para outros formatos, você precisa transformar o seu Instant
em mais flexível OffsetDateTime
.
OffsetDateTime odt = instant.atOffset( ZoneOffset.UTC );
odt.toString (): 2020-05-01T21: 25: 35.957Z
Veja esse código executado ao vivo em IdeOne.com .
Para obter uma String no formato desejado, especifique a DateTimeFormatter
. Você pode especificar um formato personalizado. Mas eu usaria um dos formatadores predefinidos ( ISO_LOCAL_DATE_TIME
) e substituiria o T
resultado em um SPACE.
String output = odt.format( DateTimeFormatter.ISO_LOCAL_DATE_TIME )
.replace( "T" , " " );
2014-11-14 14:05:09
A propósito, eu não recomendo esse tipo de formato em que você propositadamente perde as informações de deslocamento do UTC ou do fuso horário. Cria ambiguidade quanto ao significado do valor de data e hora dessa sequência.
Também tenha cuidado com a perda de dados, pois qualquer segundo fracionário está sendo ignorado (efetivamente truncado) na representação da String do valor de data e hora.
Para ver o mesmo momento pelas lentes do relógio de parede de uma determinada região , aplique a ZoneId
para obter a ZonedDateTime
.
ZoneId z = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = instant.atZone( z );
zdt.toString (): 2014-11-14T14: 05: 09-05: 00 [America / Montreal]
Para gerar uma String formatada, faça o mesmo que acima, mas substitua odt
por zdt
.
String output = zdt.format( DateTimeFormatter.ISO_LOCAL_DATE_TIME )
.replace( "T" , " " );
2014-11-14 14:05:09
Se você executar esse código várias vezes, convém ser um pouco mais eficiente e evitar a chamada para String::replace
. Interromper essa chamada também reduz seu código. Se desejar, especifique seu próprio padrão de formatação em seu próprio DateTimeFormatter
objeto. Coloque em cache esta instância como uma constante ou membro para reutilização.
DateTimeFormatter f = DateTimeFormatter.ofPattern( "uuuu-MM-dd HH:mm:ss" ); // Data-loss: Dropping any fractional second.
Aplique esse formatador passando a instância.
String output = zdt.format( f );
Sobre java.time
A estrutura java.time é integrada ao Java 8 e posterior. Essas classes suplantar as classes de data e hora velhos complicados, como java.util.Date
, .Calendar
, ejava.text.SimpleDateFormat
.
O projeto Joda-Time , agora em modo de manutenção , aconselha a migração para java.time.
Para saber mais, consulte o Tutorial do Oracle . E procure Stack Overflow para muitos exemplos e explicações.
Grande parte da funcionalidade java.time é portada para Java 6 e 7 no ThreeTen-Backport e adaptada ainda mais ao Android no ThreeTenABP (consulte Como usar ... ).
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.