Как я могу анализировать дату/время UTC (String) во что-то более читаемое?
У меня есть строка даты и времени: 2011-04-15T20:08:18Z
. Я не знаю много о форматах даты и времени, но я думаю, и исправьте меня, если я ошибаюсь, что его формат UTC.
Мой вопрос: какой самый простой способ проанализировать это в более нормальном формате на Java?
Ответы
Ответ 1
У вас есть форма даты ISO-8601, что означает, что вы можете просто использовать SimpleDateFormat
DateFormat m_ISO8601Local = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
И тогда вы можете просто использовать SimpleDateFormat.parse(). Кроме того, здесь есть сообщение в блоге с некоторыми примерами, которые могут помочь.
Update:
Прочитайте комментарии ниже, прежде чем использовать это решение.
Ответ 2
Я продолжал получать ошибки синтаксического анализа, используя другие решения с Z
в конце формата.
Вместо этого я решил использовать JodaTime отличную функциональность синтаксического анализа и смог сделать следующее очень легко:
String timestamp = "2011-04-15T20:08:18Z";
DateTime dateTime = ISODateTimeFormat.dateTimeParser().parseDateTime(timestamp);
Это правильно распознает часовой пояс UTC и позволяет затем использовать расширенные методы манипуляции JodaTime, чтобы получить то, что вы хотите от него.
Надеюсь, что это поможет другим.
В JP
Ответ 3
ТЛ; др
String output =
Instant.parse ( "2011-04-15T20:08:18Z" )
.atZone ( ZoneId.of ( "America/Montreal" ) )
.format (
DateTimeFormatter.ofLocalizedDateTime ( FormatStyle.FULL )
.withLocale ( Locale.CANADA_FRENCH )
)
;
15 августа 2011 года 16 ч 08 ПО ВОСТОЧНОМУ ВРЕМЕНИ
подробности
Ответ Джоша Пинтера правильный, но может быть еще проще.
java.time
В Java 8 и более поздних версиях связанные классы java.util.Date/Calendar заменяются структурой java.time, определенной JSR 310. Эти классы вдохновлены Joda-Time, но полностью перестроены.
Фреймворк java.time является официальным преемником Joda-Time. Создатели Joda-Time посоветовали нам перейти на java.time, как только это будет удобно. Joda-Time продолжает обновляться и дорабатываться, но дальнейшие инновации будут реализованы только в java.time и его расширениях в проекте ThreeTen-Extra.
Большая часть функциональности java.time была перенесена в Java 6 & 7 в проекте ThreeTen-Backport и дополнительно адаптирована для Android в проекте ThreeTenABP.
Эквивалент для кода Joda-Time выше очень похож. Концепции похожи. Как и Joda-Time, классы java.time по умолчанию используют форматы ISO 8601 при синтаксическом анализе/генерации текстовых представлений значений даты и времени.
Instant
- это момент времени на UTC с разрешением наносекунд (по сравнению с миллисекундами, используемыми Joda-Time & java.util.Date).
Instant instant = Instant.parse( "2011-04-15T20:08:18Z" );
Примените часовой пояс ( ZoneId
), чтобы получить ZonedDateTime
.
ZoneId zoneId = ZoneId.of( "Asia/Kolkata" );
ZonedDateTime zdt = ZonedDateTime.ofInstant( instant , zoneId );
Настройтесь на еще один часовой пояс.
ZoneId zoneId_NewYork = ZoneId.of( "America/New_York" );
ZonedDateTime zdt_NewYork = zdt.withZoneSameInstant( zoneId_NewYork );
Для создания строк в других форматах, отличных от методов toString
, используйте классы java.time.format. Вы можете указать свой собственный шаблон форматирования или позволить java.time локализоваться автоматически. Укажите Locale
для (а) человеческого языка, используемого при переводе названия месяца/дня недели, и (б) культурных норм для периода против запятой, порядка частей и т.д.
DateTimeFormatter formatter = DateTimeFormatter.ofLocalizedDateTime( FormatStyle.FULL );
formatter = formatter.withLocale( Locale.US );
String output = zdt_NewYork.format( formatter );
Пятница, 15 апреля 2011 4:08:18 ПО ВОСТОЧНОМУ ВРЕМЕНИ
О java.time
Инфраструктура java.time встроена в Java 8 и более поздние версии. Эти классы вытеснять неприятные старые устаревшие классы даты и времени, такие как java.util.Date
, Calendar
, и SimpleDateFormat
.
Проект Joda-Time, находящийся сейчас в режиме обслуживания, рекомендует перейти на классы java.time.
Чтобы узнать больше, смотрите Oracle Tutorial. И поиск для многих примеров и объяснений. Спецификация JSR 310.
Вы можете обмениваться объектами java.time напрямую с вашей базой данных. Используйте драйвер JDBC, соответствующий JDBC 4.2 или более поздней версии. Нет необходимости в строках, нет необходимости в java.sql.*
.
Где взять классы java.time?
Проект ThreeTen-Extra расширяет java.time дополнительными классами. Этот проект является полигоном для возможных будущих дополнений к java.time. Здесь вы можете найти некоторые полезные классы, такие как Interval
, YearWeek
, YearQuarter
и другие.
Joda времени
ОБНОВЛЕНИЕ: проект Joda-Time сейчас находится в режиме обслуживания, и команда советует перейти на классы java.time. Этот раздел остался нетронутым для истории.
Передать строку в конструктор
Joda-Time может взять эту строку напрямую. Просто перейдите к конструктору класса DateTime.
Joda-Time понимает стандартный формат даты-времени ISO 8601 и использует этот формат по умолчанию.
Пример кода
Вот пример кода в Joda-Time 2.3, работающего в Java 7 на Mac.
Я покажу, как передать строку в конструктор DateTime двумя способами: с часовым поясом и без него. Задание часового пояса решает многие проблемы, с которыми люди сталкиваются при работе с датой и временем. Если не указать, вы получите часовой пояс по умолчанию, который может принести сюрпризы при запуске в производство.
Я также покажу, как указать отсутствие смещения часового пояса (UTC/GMT), используя встроенную константу DateTimeZone.UTC
. То, что Z
в конце, сокращенно по Zulu
времени, означает: нет смещения часового пояса (00:00).
// © 2013 Basil Bourque. This source code may be used freely forever by anyone taking full responsibility for doing so.
// import org.joda.time.*;
// import org.joda.time.format.*;
// Default time zone.
DateTime dateTime = new DateTime( "2011-04-15T20:08:18Z" );
// Specified time zone.
DateTime dateTimeInKolkata = new DateTime( "2011-04-15T20:08:18Z", DateTimeZone.forID( "Asia/Kolkata" ) );
DateTime dateTimeInNewYork = new DateTime( "2011-04-15T20:08:18Z", DateTimeZone.forID( "America/New_York" ) );
// In UTC/GMT (no time zone offset).
DateTime dateTimeUtc = dateTimeInKolkata.toDateTime( DateTimeZone.UTC );
// Output in localized format.
DateTimeFormatter formatter = DateTimeFormat.shortDateTime().withLocale( Locale.US );
String output_US = formatter.print( dateTimeInNewYork );
Дамп на консоль…
System.out.println("dateTime: " + dateTime );
System.out.println("dateTimeInKolkata: " + dateTimeInKolkata );
System.out.println("dateTimeInNewYork: " + dateTimeInNewYork );
System.out.println("dateTimeUtc: " + dateTimeUtc );
System.out.println("dateTime in US format: " + output_US );
Когда беги…
dateTime: 2011-04-15T13:08:18.000-07:00
dateTimeInKolkata: 2011-04-16T01:38:18.000+05:30
dateTimeInNewYork: 2011-04-15T16:08:18.000-04:00
dateTimeUtc: 2011-04-15T20:08:18.000Z
dateTime in US format: 4/15/11 4:08 PM
Ответ 4
Версия Java 7 SimpleDateFormat поддерживает временные зоны ISO-8601, используя заглавную букву X
.
String string = "2011-04-15T20:08:18Z";
DateFormat iso8601 = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssX");
Date date = iso8601.parse(string);
Если вы застряли с Java 6 или ранее, ответ, рекомендующий JodaTime, является безопасной ставкой.
Ответ 5
Уже есть много ответов, но просто хотел обновить с помощью java 8, если кто-то столкнулся с проблемами при анализе строковой даты.
Вообще мы сталкиваемся с двумя проблемами с датами
- Синхронизация строк по дате
- Показать дату в формате нужной строки
DateTimeFormatter
класс в Java 8 может использоваться для обеих целей.
Ниже методы пытаются решить эти проблемы.
Метод 1:
Преобразуйте свою строку UTC в Мгновенный. Используя Мгновенный, вы можете создать дату для любого часового пояса, указав строку во временной зоне и использовать DateTimeFormatter
для форматирования даты для отображения по своему желанию.
String dateString = "2016-07-13T18:08:50.118Z";
String tz = "America/Mexico_City";
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("MMM d yyyy hh:mm a");
ZoneId zoneId = ZoneId.of(tz);
Instant instant = Instant.parse(dateString);
ZonedDateTime dateTimeInTz =ZonedDateTime.ofInstant(instant, zoneId);
System.out.println(dateTimeInTz.format(dtf));
Метод 2:
Используйте DateTimeFormatter
встроенные константы, например ISO_INSTANT
, чтобы проанализировать строку до LocalDate
.
ISO_INSTANT
может анализировать даты шаблона
yyyy-MM-dd'T'HH: mm: ssX например '2011-12-03T10: 15: 30Z'
LocalDate parsedDate
= LocalDate.parse(dateString, DateTimeFormatter.ISO_INSTANT);
DateTimeFormatter displayFormatter = DateTimeFormatter.ofPattern("yyyy MM dd");
System.out.println(parsedDate.format(displayFormatter));
Способ 3:
Если ваша строка даты имеет большую точность времени, например, она фиксирует долю секунд, а в этом случае 2016-07-13T18: 08: 50.118Z, тогда метод 1 будет работать, но метод 2 будет не работа. Если вы попытаетесь выполнить синтаксический анализ, он будет бросать DateTimeException
Так как ISO_INSTANT
, форматировщик не сможет проанализировать долю секунд, как вы можете видеть из его шаблона.
В этом случае вам нужно будет создать пользовательский DateTimeFormatter
, указав шаблон даты, как показано ниже.
LocalDate localDate
= LocalDate.parse(date, DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSX"));
Взято из ссылка в блоге, написанная мной.
Ответ 6
Вы должны указать следующий формат:
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
Date parse = simpleDateFormat.parse( "2011-04-15T20:08:18Z" );
Ответ 7
У меня была ошибка анализа в решении Andrew White.
Добавление единой цитаты вокруг Z решило проблему
DateFormat m_ISO8601Local = new SimpleDateFormat ("yyyy-MM-dd'T'HH:mm:ss'Z'");
Ответ 8
Для всех более старых версий JDK (6 down) это может быть полезно.
Избавьтесь от завершающего "Z" и заменив его буквально на отображаемое имя часового пояса "UTC" - затем разбор всей строки с использованием простейшего форматирования даты.
String timeZuluVal = "2011-04-15T20:08:18Z";
timeZuluVal = timeZuluVal.substring( 0, timeZuluVal.length() - 2 ); // strip 'Z';
timeZuluVal += " " + TimeZone.getTimeZone( "UTC" ).getDisplayName();
DateFormat simpleDateFormat = new SimpleDateFormat( "yyyy-MM-dd'T'HH:mm:ss zzzz" );
Date dateVal = simpleDateFormat.parse( timeZuluVal );
Ответ 9
шаблон в ответе @khmarbaise работал у меня, вот извлеченный метод утилиты (обратите внимание, что Z не указывается в строке шаблона):
/**
* Converts an ISO-8601 formatted UTC timestamp.
*
* @return The parsed {@link Date}, or null.
*/
@Nullable
public static Date fromIsoUtcString(String isoUtcString) {
DateFormat isoUtcFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss", Locale.getDefault());
isoUtcFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
try {
return isoUtcFormat.parse(isoUtcString);
} catch (ParseException e) {
e.printStackTrace();
return null;
}
}
Ответ 10
Время йода
public static final String SERVER_TIME_FORMAT = "yyyy-MM-dd HH:mm:ss";
public static DateTime getDateTimeFromUTC(String time) {
try {
DateTimeFormatter dateTimeFormatter = DateTimeFormat.forPattern(SERVER_TIME_FORMAT).withZoneUTC();
Calendar localTime = Calendar.getInstance();
DateTimeZone currentTimeZone = DateTimeZone.forTimeZone(localTime.getTimeZone());
return dateTimeFormatter.parseDateTime(time).toDateTime().withZone(currentTimeZone);
} catch (Exception e) {
return DateTime.now();
}
}