Конвертировать строку в 12 (PM /AM) час AM PM время до 24 часов время Android

У меня проблема с преобразованием времени с сервера, и я хочу преобразовать его в 24 часа. Я использую следующий код:

String timeComeFromServer = "3:30 PM";

SimpleDateFormat date12Format = new SimpleDateFormat("hh:mm a");

SimpleDateFormat date24Format = new SimpleDateFormat("HH:mm");
try {
    ((TextView)findViewById(R.id.ahmad)).setText(date24Format.format(date12Format.parse(timeComeFromServer)));
} catch (ParseException e) {
    e.printStackTrace();
}

Есть ошибка:

Метод сгенерировал исключение java.text.ParseException.)

Подробное сообщение об ошибке:

Неразборчивая дата: "15:30" (по смещению 5)

Но если я заменю PM в p.m. это работает без проблем, как это:

 timeComeFromServer = timeComeFromServer.replaceAll("PM", "p.m.").replaceAll("AM", "a.m.");

Кто-нибудь может сказать мне, какой путь правильный?

1 ответ

SimpleDateFormat использует язык системы по умолчанию (который вы можете проверить, используя java.util.Locale класс, зовет Locale.getDefault()). Этот языковой стандарт зависит от устройства / среды, поэтому вы не можете контролировать его и иметь разные результаты на каждом устройстве.

И некоторые локали могут иметь другой формат для поля AM/PM. Пример:

Date d = new Date();
System.out.println(new SimpleDateFormat("a", new Locale("es", "US")).format(d));
System.out.println(new SimpleDateFormat("a", Locale.ENGLISH).format(d));

Выход:

вечера
ВЕЧЕРА

Чтобы не зависеть от этого, вы можете использовать Locale.ENGLISH в ваших форматерах, так что вы не будете зависеть от конфигурации системы / устройства по умолчанию:

String timeComeFromServer = "3:30 PM";
// use English Locale
SimpleDateFormat date12Format = new SimpleDateFormat("hh:mm a", Locale.ENGLISH);
SimpleDateFormat date24Format = new SimpleDateFormat("HH:mm");
System.out.println(date24Format.format(date12Format.parse(timeComeFromServer)));

Выход:

15:30

Второй форматер не нуждается в определенной локали, поскольку он не имеет дело с информацией, специфичной для локали.


Java новый API даты / времени

Старые занятия (Date, Calendar а также SimpleDateFormat) есть много проблем и проблем дизайна, и они заменяются новыми API.

Одна деталь в том, что SimpleDateFormat всегда работает с Date объекты, которые имеют полную метку времени (число миллисекунд с 1970-01-01T00:00Z ), и оба класса implicity используют часовой пояс системы по умолчанию за кулисами, что может ввести вас в заблуждение и привести к неожиданным и трудным для отладки результатам. Но в этом конкретном случае вам нужны только поля времени (часы и минуты), и вам не нужно работать со значениями меток времени. Новый API имеет специальные классы для каждого случая, намного лучше и менее подвержен ошибкам.

В Android вы можете использовать ThreeTen Backport, отличный бэкпорт для новых классов даты / времени в Java 8. Чтобы он работал, вам также понадобится ThreeTenABP (подробнее о том, как его использовать здесь).

Вы можете использовать org.threeten.bp.format.DateTimeFormatter и проанализировать ввод в org.threeten.bp.LocalTime:

String timeComeFromServer = "3:30 PM";

DateTimeFormatter parser = DateTimeFormatter.ofPattern("h:mm a", Locale.ENGLISH);
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("HH:mm");

LocalTime time = LocalTime.parse(timeComeFromServer, parser);
System.out.println(time.format(formatter));

Выход:

15:30

Для этого конкретного случая вы также можете использовать time.toString() чтобы получить тот же результат. Вы можете обратиться к javadoc для получения дополнительной информации об API бэкпорта.

Другие вопросы по тегам