Однако я получил исключение: java.lang.IllegalArgumentException: Illegal pattern character 'T'
Итак, я задаюсь вопросом, должен ли я разделить строку и разобрать ее вручную?
Кстати, я попытался добавить символ одинарной кавычки по обе стороны от буквы T:
String pattern="yyyy-MM-dd'T'hh:mm:ssZ";
Это также не работает.
Переведено автоматически
Ответ 1
Обновление для Java 8 и выше
Теперь вы можете просто выполнить Instant.parse("2015-04-28T14:23:38.521Z") и получить правильную вещь, тем более что вы должны использовать Instant вместо сломанного java.util.Date в самых последних версиях Java.
Вы также должны использовать DateTimeFormatter вместо SimpleDateFormatter.
Оригинальный ответ:
Приведенное ниже объяснение все еще актуально в отношении того, что представляет формат. Но оно было написано до повсеместного распространения Java 8, поэтому в нем используются старые классы, которые вам не следует использовать, если вы используете Java 8 или выше.
Это работает с вводом в концеZ, как показано:
В шаблоне T экранируется с помощью ' с обеих сторон.
Шаблон для Z в конце на самом деле XXX такой, как задокументировано в JavaDoc для SimpleDateFormat, просто не очень понятно, как его использовать, поскольку Z также является маркером для старой TimeZone информации.
publicclassQ2597083 { /** * All Dates are normalized to UTC, it is up the client code to convert to the appropriate TimeZone. */ publicstaticfinal TimeZone UTC;
/** * @see <a href="http://en.wikipedia.org/wiki/ISO_8601#Combined_date_and_time_representations">Combined Date and Time Representations</a> */ publicstaticfinalStringISO_8601_24H_FULL_FORMAT="yyyy-MM-dd'T'HH:mm:ss.SSSXXX";
/** * 0001-01-01T00:00:00.000Z */ publicstaticfinal Date BEGINNING_OF_TIME;
/** * 292278994-08-17T07:12:55.807Z */ publicstaticfinal Date END_OF_TIME;
sdf.format(BEGINNING_OF_TIME) = 0001-01-01T00:00:00.000Z sdf.format(END_OF_TIME) = 292278994-08-17T07:12:55.807Z sdf.format(newDate()) = 2015-04-28T14:38:25.956Z sdf.parse("2015-04-28T14:23:38.521Z") = Tue Apr 2814:23:38 UTC 2015 sdf.parse("0001-01-01T00:00:00.000Z") = Sat Jan 0100:00:00 UTC 1 sdf.parse("292278994-08-17T07:12:55.807Z") = Sun Aug 1707:12:55 UTC 292278994
Ответ 2
tl; dr
Используйте java.time.Instant класс для разбора текста в стандартном формате ISO 8601, представляющем момент времени в UTC.
Instant.parse( "2010-10-02T12:23:23Z" )
ISO 8601
Этот формат определен в стандарте ISO 8601 для форматов строк даты и времени.
... используйте форматы ISO 8601 по умолчанию для синтаксического анализа и генерации строк.
Обычно вам следует избегать использования старого java.util.Date/ .Классы Calendar и java.text.SimpleDateFormat, как известно, являются хлопотными, запутанными и некорректными. Если требуется для взаимодействия, вы можете выполнять преобразования туда и обратно.
Instantinstant= Instant.parse( "2010-10-02T12:23:23Z" ); // `Instant` is always in UTC.
Преобразовать в старый класс.
java.util.Datedate= java.util.Date.from( instant ); // Pass an `Instant` to the `from` method.
Часовой пояс
При необходимости вы можете назначить часовой пояс.
ZoneIdzoneId= ZoneId.of( "America/Montreal" ); // Define a time zone rather than rely implicitly on JVM’s current default time zone. ZonedDateTimezdt= ZonedDateTime.ofInstant( instant , zoneId ); // Assign a time zone adjustment from UTC.
Преобразовать.
java.util.Datedate= java.util.Date.from( zdt.toInstant() ); // Extract an `Instant` from the `ZonedDateTime` to pass to the `from` method.
Joda-Time
ОБНОВЛЕНИЕ: проект Joda-Time теперь находится в режиме обслуживания. Команда рекомендует перейти на классы java.time.
Вот несколько примеров кода в Joda-Time 2.8.
org.joda.time.DateTimedateTime_Utc=newDateTime( "2010-10-02T12:23:23Z" , DateTimeZone.UTC ); // Specifying a time zone to apply, rather than implicitly assigning the JVM’s current default.
Преобразовать в старый класс. Обратите внимание, что назначенный часовой пояс теряется при преобразовании, поскольку j.u.Date не может быть назначен часовой пояс.
java.util.Datedate= dateTime_Utc.toDate(); // The `toDate` method converts to old class.
Часовой пояс
При необходимости вы можете назначить часовой пояс.
DateTimeZonezone= DateTimeZone.forID( "America/Montreal" ); DateTimedateTime_Montreal= dateTime_Utc.withZone ( zone );
Чтобы узнать больше, ознакомьтесь с Руководством по Oracle. И найдите в Stack Overflow множество примеров и пояснений. Спецификация - JSR 310.
Вы можете обмениваться объектами java.time непосредственно со своей базой данных. Используйте драйвер JDBC, совместимый с JDBC 4.2 или более поздней версии. Нет необходимости в строках, нет необходимости в java.sql.* классах.
Проект ThreeTen-Extra расширяет java.time дополнительными классами. Этот проект является испытательным полигоном для возможных будущих дополнений к java.time. Здесь вы можете найти несколько полезных классов, таких как Interval, YearWeek, YearQuarter и больше.
Ответ 3
Вы можете разобрать строку до метки времени следующим методом:
На данный момент выше есть два ответа, и оба они длинные (и tl; dr слишком короткие, ИМХО), поэтому я пишу краткое изложение своего опыта использования новой библиотеки java.time (применимо, как указано в других ответах, к Java версии 8+). ISO 8601 устанавливает стандартный способ записи дат: YYYY-MM-DD поэтому формат даты-времени такой, как показано ниже (может быть 0, 3, 6 или 9 цифр для миллисекунд), и форматирование строки не требуется: