Разбор даты с помощью SimpleDateFormat Class Android

Я знаю, что это очень известное и простое решение проблемы, которую я собираюсь здесь описать. Я пытаюсь проанализировать следующий формат даты, но получаю исключение только при анализе, даже если передаю правильный формат для анализа этой строки.

try{
  String mDateFormat = "Tue Nov 03 13:46:28 GST 2015";
  SimpleDateFormat mFormat = new SimpleDateFormat("EEE MMM dd HH:mm:ss zzz yyyy");
  Date mFormattedDate = mFormat.parse(mDateFormat);

  }catch(ParseException e){
     e.printStackTrace();
}

Часовой пояс, включенный в эту строку, вызывает только сбой. Если я удалю его, он сможет правильно его проанализировать. Итак, что-то не так с форматом часового пояса, но даже я попробовал стандарты, объявленные по этой ссылке: SimpleDateFormat По сайту разработчика

Кто-нибудь подскажет, что здесь не так?

Спасибо,


person Jai    schedule 03.11.2015    source источник
comment
со стандартными часовыми поясами вы имеете в виду замену GST на GMT и все еще не работает?   -  person Nanoc    schedule 03.11.2015
comment
Эй, у меня нормально работает код выше.   -  person M S Parmar    schedule 03.11.2015
comment
@Nanoc: Нет, это все еще не работает!   -  person Jai    schedule 03.11.2015
comment
@MiteshParmar: Могу я узнать, какую версию Android вы тестируете? и на каком конкретно устройстве работает?   -  person Jai    schedule 03.11.2015
comment
Похоже на проблему, связанную с устройством   -  person Nanoc    schedule 03.11.2015
comment
@Nanoc: я тестировал Nexus 5, Nexus 4, Samsung Galaxy S3 и S4. Ни на одном не работает! Так что это может быть не проблема, связанная с устройством. Я также проверил версию 5.1.1 и 4.4.   -  person Jai    schedule 03.11.2015
comment
Тогда как возможно, что некоторые люди сказали, что код работает, у меня нет времени, чтобы протестировать его самостоятельно, но я бы поспорил, что это конфигурация языка/часового пояса устройства, а не само устройство   -  person Nanoc    schedule 03.11.2015
comment
@Nanoc: вот почему я разместил вопрос :) Почему это не постоянное решение для всех?   -  person Jai    schedule 03.11.2015
comment
@Nanoc: Даже вижу, что я тестировал с тем же часовым поясом, что и на моем устройстве. И дело в том, что мы не можем изменить его вручную, потому что эти данные поступают из API Twitter. Так что для каждого пользователя будет разный часовой пояс :)   -  person Jai    schedule 03.11.2015


Ответы (3)


Из всех экспериментов, которые я провел до сих пор, кажется, что реализация парсера Android DateFormat, в которой вы видите проблему, не понимает зону GST. Самым простым решением было бы явно использовать средство форматирования, заменив GST на GMT+4 следующим образом:

String mDateFormat = "Tue Nov 03 13:46:28 GMT+4 2015";

С этой строкой даты Android, кажется, возвращает то же преобразование, что и эквивалент для настольного компьютера.

PS (удаление TimeZone из средства форматирования не будет правильным решением, поскольку преобразования не будут точными. Поскольку вы получаете эту дату из API Twitter, вам может потребоваться отфильтровать недопустимые строки перед форматированием на Android, который вы можете использовать:

mDateFormat.replace("GST", "GMT+4") 

перед применением DateFormat к данным.

person Nilesh Pawar    schedule 03.11.2015
comment
Привет, спасибо за ваш ответ. Так что вы имели в виду для каждой временной зоны, такой как PST, IST. GST независимо от того, что я получу, мне нужно заменить все это на GMT+4? Будет ли это точным в случае разных часовых поясов? И в этом случае мне нужно проверить каждый часовой пояс, чтобы заменить его правильно? потому что этот GST не будет исправлен, если пользователь будет использовать приложение из другой страны! - person Jai; 04.11.2015
comment
Нет. PST — это GMT-8, а IST — это GMT+5:30. Я имел в виду, что в настоящее время кажется, что Android не распознает GST. Он даже не распознает IST. Поэтому вам нужно будет дополнительно сделать: mDateFormat.replace(IST, GMT+5:30) Идея состоит в том, что когда вы получаете любой нераспознанный часовой пояс, вам может потребоваться заменить его эквивалентным номером GMT+/-. Вы можете написать небольшое приложение hello world и узнать, какие из всех возможных часовых поясов не распознаются Android (распознается PST), а затем написать для них код замены строки. - person Nilesh Pawar; 04.11.2015
comment
Вы можете получить список GMT по сравнению с другими timzeones и смещение GMT ​​по адресу timeanddate.com/time/zones. Обратите внимание, что на веб-сайте указаны смещения времени по сравнению с UTC. Но их можно применять и к GMT, поскольку между UTC и GMT нет разницы во времени. - person Nilesh Pawar; 04.11.2015

если вы используете английскую дату, измените код на

SimpleDateFormat parserSDF = new SimpleDateFormat("EEE MMM dd HH:mm:ss zzzz yyyy", Locale.ENGLISH);
person Rashim Catalan Dhaubanjar    schedule 03.11.2015
comment
Этот по-прежнему дает исключение на Android, который он получает. Оригинальный код @Jai правильно работает на рабочем столе. - person Nilesh Pawar; 03.11.2015
comment
у меня это сработало, когда в моем коде раньше возникало такое же исключение. - person Rashim Catalan Dhaubanjar; 03.11.2015
comment
Но теперь выдает исключение. невежественный!! - person Rashim Catalan Dhaubanjar; 03.11.2015

Что я сделал как простое решение:

1) Отделите часовой пояс как строку из приведенного ниже формата и замените на «»:

String mDateFormat = "Tue Nov 03 13:46:28 GST 2015";
String mTimeZone = mDateFormat.substring(20,23);
String mActualDate = mDateFormat.replace(mTimeZone + " ", "");

2) Получите часовой пояс по умолчанию и установите его при применении SimpleDateFormat

final String TWITTER = "EEE MMM dd HH:mm:ss yyyy";
SimpleDateFormat mSf = new SimpleDateFormat(TWITTER, Locale.ENGLISH);
mSf.setTimeZone(TimeZone.getDefault());
Date mNewDate = sf.parse(mActualDate);

3) Получите обновленную дату с тем же часовым поясом. Не нужно конвертировать с GMT.

person Jai    schedule 17.11.2015
comment
Причина, по которой это неправильно, заключается в том, что вы удаляете исходный часовой пояс перед попыткой преобразования. Этот новый код дает неправильный результат, если вы сравниваете вывод исходного кода, работающего на рабочем столе, с новым кодом, работающим на Android. Ниже приведены результаты выборки: Дата, использованная для теста: вторник, 03 ноября, 13:46:28 GST 2015; Исходный код из вашего вопроса на рабочем столе преобразует это в: вторник, 03 ноября, 04:46:28 EST 2015. Ваш новый код преобразует это в: вторник, 03 ноября, 13:46:28 EST 201. Обратите внимание на разницу во времени 4 против 13. Если код был правильным, результаты должны совпадать. - person Nilesh Pawar; 17.11.2015
comment
Чтобы дать небольшую аналогию того, почему исходный часовой пояс важно сохранить до преобразования даты, можно сделать следующее. Предположим, вам нужно конвертировать валюту, скажем, из 1 доллара в иену. С помощью вашего нового метода вы удаляете $ (это похоже на валютную зону), а затем вставляете валюту Locale. Таким образом, по вашему методу 1 доллар = 1 иена, что неверно. По сути, удаляя $, вы изменяете вопрос с «Что такое 1 доллар, конвертированный в иену», на «Что такое 1 иена, конвертированная в иену», что дает ошибочные результаты. - person Nilesh Pawar; 17.11.2015
comment
@NileshPawar: Чувак, я удаляю исходный часовой пояс, но добавляю тот же часовой пояс, если вы проверите с помощью метода setTimeZone, который я использовал. - person Jai; 18.11.2015
comment
@NileshPawar: И ваш рабочий стол может иметь время EST. Вот почему он конвертируется в EST. но это неправильная проверка, которую вы проверяете. Потому что GST был жесткой строкой для меня, потому что я нахожусь в часовом поясе GST. Если вы прочитаете какие-либо данные из twitter api, вы получите EST в результате, а не GST, поэтому мой процесс сначала просто удалит его, а затем снова добавит ваш часовой пояс EST вашего рабочего стола. Так что, пожалуйста, поймите процесс :) - person Jai; 18.11.2015
comment
@NileshPawar: для вашего тестового примера вы должны использовать 03 ноября 13:46:28 EST 2015 вместо GST. Тогда у вас будет точный результат. И это то, что мы должны попробовать. Конечно, это не сработает, если вы введете GST и добавите EST (в качестве часового пояса по умолчанию в вашей системе). :) - person Jai; 18.11.2015
comment
@NileshPawar: исходная проблема заключалась в том, что Android не может разобрать этот формат. Таким образом, формат был исходной проблемой. Я упомянул, что это может быть что угодно вроде GST, EST или IST, это зависит от местоположения пользователя. Вот почему я сделал простое решение, удалив и добавив часовой пояс по умолчанию для пользователей. Потому что часовой пояс, полученный в API, равен часовому поясу по умолчанию для местоположения пользователя. Решение было дано вами, чтобы заменить его на GMT, для этого мне нужно проверить каждый часовой пояс с соответствующим значением GMT. :) - person Jai; 18.11.2015
comment
Не уверен в потоке данных в вашем случае. Если дата, которую вы получаете от twitter API, генерируется из того же часового пояса, что и пользователь устройства, она будет работать. Однако, если ваше приложение получает даты, сгенерированные в каком-то другом часовом поясе, отличном от часового пояса пользователя устройства, оно явно потерпит неудачу. Например, если API Twitter отправляет вам дату для чего-то, что было сгенерировано в ОАЭ, а ваше приложение работает в Австралии, оно будет отображаться неправильно. - person Nilesh Pawar; 18.11.2015
comment
@NileshPawar: Но этого не будет, верно? Потому что не только в твиттере, но и в любых других SDK, а также, когда вы запрашиваете данные, они дадут вам данные только с вашим часовым поясом. :) Так что, по крайней мере, уберите минусовую оценку, чтобы это могло быть полезно для других парней :) - person Jai; 18.11.2015