ТЛ; др
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
Современный способ заключается в использовании классов java.time, которые теперь вытесняют проблемные старые унаследованные классы даты и времени.
Сначала конвертируйте java.util.Date
в Instant
. Instant
Класс представляет собой момент на шкале времени в формате UTC с разрешением наносекунд (до девяти (9) цифр десятичной дроби).
Преобразование в / из java.time выполняется новыми методами, добавленными к старым классам.
Instant instant = myUtilDate.toInstant();
И твой java.util.Date
и java.time.Instant
в UTC . Если вы хотите видеть дату и время как UTC, пусть будет так. Вызов toString
для генерации строки в стандартном формате ISO 8601 .
String output = instant.toString();
2014-11-14T14: 05: 09Z
Для других форматов вам нужно превратить ваш Instant
в более гибкий OffsetDateTime
.
OffsetDateTime odt = instant.atOffset( ZoneOffset.UTC );
odt.toString (): 2020-05-01T21: 25: 35.957Z
Посмотрите, как работает этот код на IdeOne.com .
Чтобы получить строку в желаемом формате, укажите DateTimeFormatter
. Вы можете указать пользовательский формат. Но я бы использовал один из предопределенных форматеров ( ISO_LOCAL_DATE_TIME
) и заменил бы T
в его выводе пробел.
String output = odt.format( DateTimeFormatter.ISO_LOCAL_DATE_TIME )
.replace( "T" , " " );
2014-11-14 14:05:09
Кстати, я не рекомендую такой формат, когда вы намеренно теряете смещение от UTC или информацию о часовом поясе. Создает неоднозначность относительно значения даты-времени этой строки.
Также остерегайтесь потери данных, поскольку любая дробная секунда игнорируется (эффективно усекается) в представлении вашей строки значения даты и времени.
Чтобы увидеть тот же момент через призму часов определенного региона , примените a, ZoneId
чтобы получить a ZonedDateTime
.
ZoneId z = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = instant.atZone( z );
zdt.toString (): 2014-11-14T14: 05: 09-05: 00 [Америка / Монреаль]
Чтобы создать форматированную строку, сделайте то же, что и выше, но замените odt
на zdt
.
String output = zdt.format( DateTimeFormatter.ISO_LOCAL_DATE_TIME )
.replace( "T" , " " );
2014-11-14 14:05:09
Если этот код выполняется очень много раз, вы можете захотеть быть более эффективным и избегать вызова String::replace
. Удаление этого вызова также делает ваш код короче. При желании укажите свой собственный шаблон форматирования в своем собственном DateTimeFormatter
объекте. Кэшируйте этот экземпляр как константу или член для повторного использования.
DateTimeFormatter f = DateTimeFormatter.ofPattern( "uuuu-MM-dd HH:mm:ss" ); // Data-loss: Dropping any fractional second.
Примените этот форматер, передав экземпляр.
String output = zdt.format( f );
О java.time
Java.time каркас встроен в Java 8 и более поздних версий. Эти классы вытеснять неприятные старые классы даты и времени , такие как java.util.Date
, .Calendar
, и java.text.SimpleDateFormat
.
Проект Joda-Time , находящийся сейчас в режиме обслуживания , рекомендует перейти на java.time.
Чтобы узнать больше, смотрите Oracle Tutorial . И поиск переполнения стека для многих примеров и объяснений.
Большая часть функциональности java.time перенесена на Java 6 и 7 в ThreeTen-Backport и дополнительно адаптирована для Android в ThreeTenABP (см. Как использовать… ).
Проект ThreeTen-Extra расширяет java.time дополнительными классами. Этот проект является полигоном для возможных будущих дополнений к java.time.