ТЛ; др
LocalDateTime.parse( // Parse string as value without time zone and without offset-from-UTC.
"2017-01-23 12:34 PM" ,
DateTimeFormatter.ofPattern( "uuuu-MM-dd hh:mm a" )
) // Returns a `LocalDateTime` object.
.atZone( ZoneId.of( "America/Montreal" ) ) // Assign time zone, to determine a moment. Returns a `ZonedDateTime` object.
.toInstant() // Adjusts from zone to UTC.
.toString() // Generate string: 2017-01-23T17:34:00Z
.replace( "T" , " " ) // Substitute SPACE for 'T' in middle.
.replace( "Z" , " Z" ) // Insert SPACE before 'Z'.
Избегайте устаревших классов даты и времени
В других ответах используются старые классы даты и времени (Date
, Calendar
и т. Д.), Которые теперь унаследованы и заменены классами java.time.
LocalDateTime
У меня есть строка в шаблоне гггг-мм-дд чч: мм а
В такой входной строке отсутствует указание смещения от UTC или часового пояса. Таким образом, мы разбираем как LocalDateTime
.
Определите шаблон форматирования, соответствующий вашему вводу с DateTimeFormatter
объектом.
String input = "2017-01-23 12:34 PM" ;
DateTimeFormatter f = DateTimeFormatter.ofPattern( "uuuu-MM-dd hh:mm a" );
LocalDateTime ldt = LocalDateTime.parse( input , f );
ldt.toString (): 2017-01-23T12: 34
Обратите внимание, что LocalDateTime
- это , а не конкретный момент, только смутное представление о диапазоне возможных моментов. Например, через несколько минут после полуночи в Париже Франция все еще «вчера» в Монреале, Канада. Поэтому без контекста часового пояса, такого как Europe/Paris
или America/Montreal
, просто говорить «через несколько минут после полуночи» не имеет смысла.
ZoneId
и я могу получить объект часового пояса отдельно, в котором приведенная выше строка представляет дату.
Часовой пояс представлен классом ZoneId
.
Укажите собственное имя часового пояса в формате continent/region
, например America/Montreal
, Africa/Casablanca
или Pacific/Auckland
. Никогда не используйте 3-4-буквенное сокращение, например EST
или IST
, поскольку они не истинных часовых поясов, не стандартизированы и даже не уникальны (!).
ZoneId z = ZoneId.of( "America/Montreal" );
ZonedDateTime
Примените ZoneId
, чтобы получить ZonedDateTime
, который действительно является точкой на временной шкале, конкретным моментом в истории.
ZonedDateTime zdt = ldt.atZone( z );
zdt.toString (): 2017-01-23T12: 34-05: 00 [Америка / Монреаль]
Instant
Я хочу преобразовать это в приведенный ниже формат. гггг-мм-дд чч: мм: сс z
Во-первых, знайте, что буквенный символ Z
является сокращением от Zulu
и означает UTC . Другими словами, смещение от UTC нулевых часов, +00:00
.
Класс Instant
представляет момент на временной шкале в UTC с разрешением наносекунд (до девяти (9) цифр десятичного знака доля).
Вы можете извлечь Instant
объект из ZonedDateTime
.
Instant instant = zdt.toInstant(); // Extracting the same moment but in UTC.
Для генерации строки в стандартном формате ISO 8601 , например 2017-01-22T18:21:13.354Z
, позвоните toString
. Стандартный формат не имеет пробелов, использует T
для отделения даты год-месяц от часа-минуты-секунды и добавляет Z
канонически для смещения нуля.
String output = instant.toString();
instant.toString (): 2017-01-23T17: 34: 00Z
Я настоятельно рекомендую использовать стандартные форматы, когда это возможно. Если вы настаиваете на использовании пробелов в указанном вами желаемом формате, либо определите свой собственный шаблон форматирования в объекте DateTimeFormatter
или просто выполните строковую манипуляцию с выводом Instant::toString
.
String output = instant.toString()
.replace( "T" , " " ) // Substitute SPACE for T.
.replace( "Z" , " Z" ); // Insert SPACE before Z.
вывод: 2017-01-23 17:34:00 Z
Попробуйте этот код в прямом эфире на IdeOne.com .
О java.time
Фреймворк java.time встроен в Java 8 и более поздние версии. Эти классы заменяют проблемные старые устаревшие классы даты и времени, такие как java.util.Date
, Calendar
, & SimpleDateFormat
.
Проект Joda-Time , в настоящее время находящийся в режиме обслуживания , рекомендует перейти на классы java.time .
Чтобы узнать больше, см. Oracle Tutorial . И поиск переполнения стека для многих примеров и объяснений. Спецификация JSR 310 .
Где получить классы java.time?
- Java SE 8 и SE 9 и более поздние
- Встроенный.
- Часть стандартного Java API с встроенной реализацией.
- Java 9 добавляет некоторые незначительные функции и исправления.
- Java SE 6 и SE 7
- Android
Проект ThreeTen-Extra расширяет java.time сдополнительные занятия.Этот проект является полигоном для возможных будущих дополнений к java.time.Здесь вы можете найти несколько полезных классов, таких как Interval
, YearWeek
, YearQuarter
и more .