Неизвестный символ шаблона «x» при использовании SimpleDateFormat

Я пытаюсь отформатировать Date в String, используя SimpleDateFormat, и я использую этот шаблон.

"гггг-ММ-дд'Т'ЧЧ:мм:сс.SSSxxx"

но когда дойти до этой строки

SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSxxx");

я получаю следующее исключение:

java.lang.IllegalArgumentException: Неизвестный символ шаблона 'x' в java.text.SimpleDateFormat.validatePatternCharacter(SimpleDateFormat.java:323) в java.text.SimpleDateFormat.validatePattern(SimpleDateFormat.java:312) в java.text.SimpleDateFormat.( SimpleDateFormat.java:365) в java.text.SimpleDateFormat.(SimpleDateFormat.java:258)

формат, которого я пытаюсь добиться, - "2017-06-16T12:19:59.001+02:00"

согласно документации, этот шаблон должен работать. Что не так?

EDIT Чтобы уточнить, я пробовал с xxx и XXX

в случае XXX я получаю java.lang.IllegalArgumentException: неизвестный символ шаблона «X»


person Ric    schedule 16.06.2017    source источник
comment
Вы прикрепили шаблон с заглавной буквой X, а в документации сказано, что она должна быть строчной x. Но затем стек исключений снова говорит о нижнем регистре x. Не могли бы вы пояснить это?   -  person M. Prokhorov    schedule 16.06.2017
comment
«X» для часового пояса — это относительно новая функция в SimpleDateFormat. Если вы запустите его на версии Android, поддерживающей только Java 6, он не будет работать.   -  person Balázs Nemes    schedule 16.06.2017
comment
да, но я пробовал и верхний, и нижний регистр.   -  person Ric    schedule 16.06.2017
comment
@BalázsNemes какая альтернатива?   -  person Ric    schedule 16.06.2017
comment
Вместо этого вы можете использовать Z, как подсказывает ответ.   -  person Balázs Nemes    schedule 16.06.2017
comment
Я действительно понятия не имею,. Это совершенно правильный вопрос. Так как, в отличие от Java SE, старые версии Android не поддерживают X. Я понятия не имею, почему люди хотят проголосовать за этот вопрос без причины. Я собираюсь проголосовать за этот вопрос.   -  person Cheok Yan Cheng    schedule 27.01.2018


Ответы (5)


См. Обновление ниже.

К сожалению, что касается прописных букв X, документация [была на момент вопроса и этого ответа] неправильной. Поскольку документация, похоже, имеет значительно изменился в отношении x и X, я продолжайте и заявите здесь, что прямо сейчас здесь написано, что X (верхний регистр) поддерживается (начиная с уровня API 1), но x (нижний регистр) вообще не упоминается. документы, используемые для также не упоминайте X.

Проверка Android исходный код (см. validateFormat()) показывает, что в этой версии распознаются только буквы GyMdkHmsSEDFwWahKzZLc, несмотря на заявление документации о том, что X поддерживается с уровня API 1. Это объясняет, почему вы получаете IllegalArgumentException: Unknown pattern character 'X'.

Подробнее см. в этом отчете об ошибке.

Между тем, вам придется найти обходной путь, который будет зависеть от того, какие входные данные вам нужно проанализировать. Например. ответ OP.

Обновление: X доступен только в Nougat+.

В документации исправлено добавление столбца "Поддерживаемые (уровни API)", в котором указано, что X поддерживается только начиная с уровня API 24. Предположительно, IllegalArgumentException ОП был связан с тестированием приложения на устройстве до 24, поскольку ранее в документах ничего не говорилось о поддерживаемых уровнях API.

person LarsH    schedule 20.10.2017

Кажется, я нашел ответ в проблеме на GitHub :

Вы правы, Android вместо этого использует ZZZZZ для создания часового пояса, такого как +01:00 (например, XXX в Java). А пока не могли бы вы попробовать использовать метод ApiClient#setDatetimeFormat для настройки формата даты и времени, чтобы он работал в Android?

Возьмем образец зоомагазина в качестве примера:

// import io.swagger.client.Configuration;
// import io.swagger.client.ApiClient;
// import java.text.SimpleDateFormat;

// Customize for the default ApiClient
Configuration.getDefaultApiClient().setDatetimeFormat(new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZZZZZ"));

// Customize for a new ApiClient
ApiClient apiClient = new ApiClient();
apiClient.setDatetimeFormat(new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZZZZZ"));
// Use the new ApiClient
PetApi api = new PetApi(apiClient);
api.getPetById(new Long(1));

Видимо, я должен использовать:

yyyy-MM-dd'T'HH:mm:ss.SSSZZZZZ  
person Ric    schedule 16.06.2017
comment
это решило мою проблему. Я использую регулярное выражение для проверки ISO8601: regex101.com/r/b3GJso/1 , затем переопределите parse(dateString), чтобы использовать нормализованную строку в URL github здесь, в противном случае просто используйте super.parse(dateString) - person mochadwi; 12.06.2020

Вам нужен шаблон "yyyy-MM-dd'T'HH:mm:ss.SSSXXX", но в исключении упоминается строчная буква x. Похоже, у вас где-то опечатка.

person Demogorii    schedule 16.06.2017
comment
я пробовал как верхний, так и нижний регистр, плохо редактирую вопрос, чтобы уточнить - person Ric; 16.06.2017
comment
Кроме того, в примерах, которые они показывают в документации, они имеют гггг-ММ-дд'Т'ЧЧ:мм:сс.SSSXXX 2001-07-04T12:08:56.235-07:00 - person Ric; 16.06.2017
comment
Вы должны использовать ПРОПИСНЫЕ буквы абсолютно. Вроде упоминаю. Что является исключением, когда вы используете ПРОПИСНЫЕ X? - person Demogorii; 16.06.2017
comment
java.lang.IllegalArgumentException: неизвестный символ шаблона 'X' - person Ric; 16.06.2017

Используйте это вместо этого:

SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZZZZZ");

person Shujat Munawar    schedule 27.11.2017

я думаю, вы ищете "yyyy-MM-dd'T'HH:mm:ss.SSSZ"

Изменить формат даты на

DateFormat df = new SimpleDateFormat («гггг-ММ-дд'Т'ЧЧ: мм: сс.ССС"); или же

DateFormat df = new SimpleDateFormat ("гггг-ММ-дд'Т'ЧЧ: мм: ссZ");

это может тебе помочь

person Vij    schedule 16.06.2017
comment
Z — это часовой пояс в стиле RFC, а другой — часовой пояс в стиле ISO. Я не думаю, что они будут работать в целом (они могут быть для некоторых особых случаев). - person M. Prokhorov; 16.06.2017
comment
вы можете обратиться к developer.android.com/reference/java/text/SimpleDateFormat.html - person Vij; 16.06.2017
comment
где маленький z используется для общего часового пояса - person Vij; 16.06.2017
comment
SimpleDateFormat sdf = новый SimpleDateFormat (гггг-ММ-дд'T'ЧЧ: мм: ссZ, Locale.UK); Строка formattedDate = sdf.format (новая дата ()); - person Vij; 16.06.2017