Подтвердить что ты не робот

Как я могу анализировать дату/время UTC (String) во что-то более читаемое?

У меня есть строка даты и времени: 2011-04-15T20:08:18Z. Я не знаю много о форматах даты и времени, но я думаю, и исправьте меня, если я ошибаюсь, что его формат UTC.

Мой вопрос: какой самый простой способ проанализировать это в более нормальном формате на Java?

4b9b3361

Ответ 1

У вас есть форма даты ISO-8601, что означает, что вы можете просто использовать SimpleDateFormat

DateFormat m_ISO8601Local = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");

И тогда вы можете просто использовать SimpleDateFormat.parse(). Кроме того, здесь есть сообщение в блоге с некоторыми примерами, которые могут помочь.

Update:

Прочитайте комментарии ниже, прежде чем использовать это решение.

Ответ 2

Используйте JodaTime

Я продолжал получать ошибки синтаксического анализа, используя другие решения с 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?

  • Java SE 8, Java SE 9, Java SE 10 и более поздние версии
    • Встроенный.
    • Часть стандартного Java API со встроенной реализацией.
    • Java 9 добавляет некоторые незначительные функции и исправления.
  • Java SE 6 и Java SE 7
    • Большая часть функциональности java.time перенесена на Java 6 и 7 в ThreeTen-Backport.
  • Android
    • Более поздние версии Android связывают реализации классов java.time.
    • Для более ранних версий Android (<26) проект ThreeTenABP адаптирует ThreeTen-Backport (упомянутый выше). Смотрите Как использовать ThreeTenABP….

Проект 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();
    }
}