Проблема SimpleDateFormat при разборе строки в формате ISO 8601

Благодарю, что есть много похожих постов на эту тему, но я не смог найти конкретный, который мог бы помочь.

Я пытаюсь преобразовать эту строку в дату в Java

2017-05-16 06:24:36-0700

Но он каждый раз терпит неудачу с этим кодом

Date Login = new SimpleDateFormat("dd/MM/yy HH:mm:ss").parse("2017-05-16 06:24:36-0700");

Теперь я предполагаю, что это связано с информацией о часовом поясе в конце - я просто не могу понять, как установить формат. Я пробовал это, но не повезло

SimpleDateFormat("dd/MM/yy HH:mm:ssZ")

Любые идеи?


person reviloSlater    schedule 16.05.2017    source источник
comment
Что ж, я предлагаю перейти сюда: stackoverflow.com/questions /18122608/   -  person ItamarG3    schedule 16.05.2017
comment
Ваша дата имеет год-месяц-день с дефисами между ними, и вы пытаетесь проанализировать ее в формате, который имеет противоположный порядок, день-месяц-год и косые черты вместо дефисов?   -  person Ole V.V.    schedule 16.05.2017
comment
Насколько я помню, SimpleDateFormat.parse() с одним аргументом игнорирует любые лишние символы в конце строки, например ваш часовой пояс. Поэтому я сомневаюсь, что его наличие является вашей проблемой.   -  person Ole V.V.    schedule 16.05.2017


Ответы (2)


Формат даты, переданный вашему SimpleDateFormat, равен "dd/MM/yy", а дата, которую вы пытаетесь проанализировать, имеет формат "yyyy-MM-dd". Попробуйте это вместо этого:

Date login = new SimpleDateFormat("yyyy-MM-dd HH:mm:ssZ").parse("2017-05-16 06:24:36-0700");

В качестве примечания: в зависимости от того, какую версию Java вы используете, я бы рекомендовал использовать новый пакет java.time (JDK 1.8+) или обратный порт этого пакета (JDK 1.6+) вместо устаревших (не каламбур) классов Date и/или Calendar.

Instant login = Instant.from(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ssZ").parse("2017-05-16 06:24:36-0700"));
person Bryan    schedule 16.05.2017
comment
Да, вы правы, я передал дату в неправильном формате. Ошибка новичка... спасибо за указатель - person reviloSlater; 16.05.2017
comment
В java.time проще заменить ПРОБЕЛ в середине на T для соответствия ISO 8601. Затем проанализируйте напрямую: OffsetDateTime.parse( "2017-05-16 06:24:36-0700".replace( " " , "T" ) ) - person Basil Bourque; 16.05.2017
comment
@BasilBourque, мне не удалось заставить это работать в Java 8 (текст «2017-05-16T06:24:36-0700» не удалось проанализировать по индексу 19). В смещении требуется двоеточие, -07:00. Я думаю, вы однажды сказали нам, что это работает в Java 9. - person Ole V.V.; 16.05.2017
comment
@ОлеВ.В. Да, действительно, насколько я сейчас припоминаю, невозможность проанализировать смещение без двоеточия — это ошибка в Java 8, исправленная в Java 9. См. запуск кода в прямом эфире на IdeOne.com. - person Basil Bourque; 17.05.2017

Я уже проголосовал за ответ Брайана именно потому, что он включает и рекомендует решение java.time. Однако мне нужно добавить несколько мыслей.

Ваш код, reviloSlater, выбрасывает информацию о часовом поясе (точнее, информацию о смещении зоны), я не уверен, что осмелился бы сделать это с самого начала. С классами java.time более естественно включать его, и его легко отбросить позже, когда мы уверены, что он нам не нужен.

Для разбора со смещением:

    OffsetDateTime loginOdt = OffsetDateTime.parse("2017-05-16 06:24:36-0700",
            DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ssZ"));

Удаление информации о смещении часового пояса

    LocalDateTime loginLdt = loginOdt.toLocalDateTime();

LocalDateTime — это дата и время без какой-либо информации о часовом поясе или смещении. В этом случае, конечно, мы получаем

2017-05-16T06:24:36

Код Брайана java.time также использует информацию о смещении часового пояса из строки. Редактировать: после редактирования Брайаном этот код теперь работает и дает нам:

2017-05-16T13:24:36Z

Это тот же момент времени (Instant.toString() печатает время в формате UTC). Другой способ: с OffsetDateTime до того, как мы можем просто сделать

    Instant login = loginOdt.toInstant();

java.time загружается с возможностями.

person Ole V.V.    schedule 16.05.2017