Проблемы с анализом дат с помощью DateUtils
Я пытаюсь разобрать несколько разных строк даты для приложения Android.
Вот два примера:
Thu, 20 Aug 2020 13:30:16 +0000
Wed, 19 Aug 2020 15:28:47 GMT
Вот как я пытался разобрать эти строки:
Date pubDate = org.apache.commons.lang3.time.DateUtils.parseDate(dateString,
"EEE, dd MMM yyyy HH:mm:ss Z", "EEE, dd MMM yyyy HH:mm:ss zzz");
Насколько я могу судить, это должно работать, но я получаю java.text.ParseException: Unable to parse the date: Wed, 19 Aug 2020 15:28:47 GMT
исключения для обоих этих примеров. Что я здесь делаю не так?
3 ответа
Ваш формат встроен в java.time
Использовать DateTimeFormatter.RFC_1123_DATE_TIME
; он работает для обеих ваших струн. Это действительно тот же формат, только смещение от UTC (или GMT) обозначено иначе.DateTimeFormatter
является частью java.time, современного API даты и времени Java. Я рекомендую вам предпочесть java.timeDate
а также DateUtils
, также потому, что Date
класс плохо спроектирован и давно устарел.
String s = "Thu, 20 Aug 2020 13:30:16 +0000";
OffsetDateTime dt = OffsetDateTime.parse(s, DateTimeFormatter.RFC_1123_DATE_TIME);
System.out.println(dt);
Выход:
2020-08-20T13:30:16Z
Давайте попробуем с другим примером строки:
String s = "Wed, 19 Aug 2020 15:28:47 GMT";
2020-08-19T15:28:47Z
Вопрос: Разве java.time не требует Android API 26 уровня?
java.time прекрасно работает как на старых, так и на новых устройствах Android. Просто требуется как минимум Java 6.
- В Java 8 и новее, а также на новых устройствах Android (начиная с уровня API 26) современный API встроен.
- В Java 6 и 7, отличных от Android, используйте ThreeTen Backport, бэкпорт современных классов (ThreeTen для JSR 310; см. Ссылки внизу).
- На более старых версиях Android используйте Desugaring или версию ThreeTen Backport для Android. Это называется ThreeTenABP. В последнем случае убедитесь, что вы импортируете классы даты и времени из
org.threeten.bp
с подпакетами.
Ссылки
- Учебник Oracle: Date Time, объясняющий, как использовать java.time.
- Запрос спецификации Java (JSR) 310, где
java.time
был впервые описан. - Проект ThreeTen Backport, то портировать из
java.time
на Java 6 и 7 (ThreeTen для JSR-310). - API-интерфейсы Java 8+, доступные через обессахаривание
- ThreeTenABP, версия ThreeTen Backport для Android
- Вопрос: как использовать ThreeTenABP в Android Project, с очень подробным объяснением.
Ваши часовые пояса представлены в двух разных форматах: https://docs.oracle.com/javase/7/docs/api/java/text/SimpleDateFormat.html
Первый выглядит так, как будто он соответствует формату:
EEE, dd MMM yyyy HH:mm:ss Z", "EEE, dd MMM yyyy HH:mm:ss Z
А второй имеет формат:
EEE, dd MMM yyyy HH:mm:ss Z", "EEE, dd MMM yyyy HH:mm:ss z
Не вижу проблем с вашими форматами.
Демо:
import java.text.ParseException;
import java.util.Date;
public class Main {
public static void main(String[] args) throws ParseException {
String[] dateStrings = { "Wed, 19 Aug 2020 15:28:47 GMT", "Thu, 20 Aug 2020 13:30:16 +0000" };
for (String dateString : dateStrings) {
Date pubDate = org.apache.commons.lang3.time.DateUtils.parseDate(dateString, "EEE, dd MMM yyyy HH:mm:ss Z",
"EEE, dd MMM yyyy HH:mm:ss zzz");
System.out.println(pubDate);
}
}
}
Выход:
Wed Aug 19 16:28:47 BST 2020
Thu Aug 20 14:30:16 BST 2020
Однако я настоятельно рекомендую вам перестать использовать устаревшие и подверженные ошибкамjava.util
API даты и времени и SimpleDateFormat
. Переходи на современное java.time
API даты и времени и соответствующий API форматирования (java.time.format
). Узнайте больше о современном API даты и времени из Trail: Date Time.
Используя современный API даты и времени:
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Locale;
public class Main {
public static void main(String[] args) {
// Test strings
String[] dateStrings = { "Wed, 19 Aug 2020 15:28:47 GMT", "Thu, 20 Aug 2020 13:30:16 +0000" };
// Define formatter
DateTimeFormatter formatter = DateTimeFormatter
.ofPattern("[EEE, dd MMM yyyy HH:mm:ss Z][EEE, dd MMM yyyy HH:mm:ss zzz]", Locale.ENGLISH);
for (String dateString : dateStrings) {
ZonedDateTime zdt = ZonedDateTime.parse(dateString, formatter);
System.out.println(zdt);
}
}
}
Выход:
2020-08-19T15:28:47Z[GMT]
2020-08-20T13:30:16Z
Если ваша версия Android несовместима с Java-8, вы можете выполнить резервное копирование с помощью ThreeTen-BackportCheck. Проверьте, как использовать ThreeTenABP в Android Project