Java: DATE_EXCEPTION Неразборная дата: 2017-06-28 08:30 (по смещению 17)

Я хотел получить объект java.util.Date, проанализировав дату строки: «2017-06-28 08:30». Этот синтаксический анализ используется в моем приложении для Android. Это работает без каких-либо исключений синтаксического анализа во многих версиях Android. Вроде 7.0, 4.4.2 и 5.1. Но это не работает в Android 6.0.

Это мой журнал ошибок и SimpleDateFormat,

W/System.err: java.text.ParseException: Unparseable date: "2017-06-28 08:30 AM" (at offset 17)
at java.text.DateFormat.parse(DateFormat.java:579)
at biz.spsolutions.peopleedge.RosterClockInActivity.setData(RosterClockInActivity.java:531)
at biz.spsolutions.peopleedge.RosterClockInActivity.onCreate(RosterClockInActivity.java:391)
at android.app.Activity.performCreate(Activity.java:6877)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1136)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3208)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3351)
at android.app.ActivityThread.access$1100(ActivityThread.java:222)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1796)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:158)
at android.app.ActivityThread.main(ActivityThread.java:7230)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1120)

А это мой SimpleDateFormat,

SimpleDateFormat currentFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm a")

Также я пробовал и в этом формате,

SimpleDateFormat currentFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm aaa")

Как я могу обработать это исключение? Есть идеи?


person Terance    schedule 28.06.2017    source источник
comment
попробуй это 2017-06-28 08:30 am   -  person M D    schedule 28.06.2017
comment
Проверка @Barrier brightec.co.uk/ideas/android-marshmallow-and -simpledateformat, если это поможет.   -  person gvmani    schedule 28.06.2017
comment
@M D : Хорошо, я постараюсь сообщить вам   -  person Terance    schedule 28.06.2017
comment
@gvmani: это не работает. Я пробовал.   -  person Terance    schedule 28.06.2017
comment
какая у тебя локаль? (если это не по-английски, AM/PM ничего не значит)   -  person njzk2    schedule 28.06.2017
comment
Оба ваших формата работают на моем компьютере (за исключением того, что вам не хватает точки с запятой). Однако я бы предпочел некоторые изменения: (1) дать явную локаль, как в new SimpleDateFormat("yyyy-MM-dd hh:mm a", Locale.ENGLISH); это, вероятно, решит вашу проблему. (2) Укажите явный часовой пояс: currentFormat.setTimeZone(TimeZone.getTimeZone("Asia/Harbin"));. (3) Лучше всего получить ThreeTenABP и использовать Ответ Бэзила Бурка.   -  person Ole V.V.    schedule 28.06.2017


Ответы (1)


tl;dr

Нет проблем при использовании современных классов java.time.

LocalDateTime.parse( 
    "2017-06-28 08:30 AM" , 
    DateTimeFormatter.ofPattern( "uuuu-MM-dd hh:mm a" , Locale.US ) 
)

2017-06-28T08:30

Использование java.time

Вы используете неприятные старые классы даты и времени, которые теперь являются устаревшими, вытесненными классами java.time. Для Android см. последний пункт ниже.

Обратите внимание, что я указываю Locale.US как часть моего средства форматирования. Регион определяет культурные нормы, используемые при определении таких вопросов, как использование заглавных букв. Я подозреваю, что текущее значение по умолчанию вашей JVM может быть установлено на локаль, ожидающую, что «AM/PM» будет в нижнем регистре. Всегда указывайте ожидаемую/желаемую локаль, а не неявно полагайтесь на текущую локаль по умолчанию, которая может быть изменена в любое время любым кодом в приложении вашей JVM. Дополнительные сведения см. в разделе другой вопрос.

String input = "2017-06-28 08:30 AM" ;
DateTimeFormatter f = DateTimeFormatter.ofPattern( "uuuu-MM-dd hh:mm a" , Locale.US ) ;
LocalDateTime ldt = LocalDateTime.parse( input , f ) ;

Посмотрите этот код, запущенный в прямом эфире на IdeOne.com.

ldt.toString(): 2017-06-28T08:30


О java.time

Платформа java.time встроен в Java 8 и более поздние версии. Эти классы заменяют проблемные старые устаревшие классы даты и времени, такие как java.util.Date, Calendar и SimpleDateFormat.

Проект Joda-Time, теперь в режим обслуживания, советует перейти на java.time.

Чтобы узнать больше, см. учебник по Oracle. И поищите множество примеров и пояснений в Stack Overflow. Спецификация: JSR 310.

Где получить классы java.time?

person Basil Bourque    schedule 28.06.2017
comment
@DawoodibnKareem (a) Обратите внимание, что я показал использование Locale в своем ответе. (b) Просто нет причин использовать чертовски ужасный беспорядок, который представляет собой старые классы Date/Calendar/SimpleDateFormat. Я утверждаю, что отказ от этих классов является правильным решением для каждого такого Вопроса. (c) Я добавлю конкретное упоминание о том, что локаль является возможной причиной проблемы. - person Basil Bourque; 28.06.2017
comment
@DawoodibnKareem, я понимаю твою точку зрения. Я также согласен с вами в том, что проблема ОП, скорее всего, связана с локалью. Ответ действительно дает правильную локаль для входной строки и, следовательно, решает проблему. Stack Overflow приветствует решение проблемы другим способом, отличным от ожидаемого, и помогло тысячам пользователей, часто даже лучше, чем они ожидали. Хотя это может быть не тот ответ, о котором просили, он все же может быть ответом, который хочет ОП. - person Ole V.V.; 28.06.2017
comment
@ОлеВ.В. Ты прав. Настоящим я снимаю свое возражение и ставлю заслуженный голос "за". - person Dawood ibn Kareem; 28.06.2017