Форматирование даты на основе локали пользователя на Android
Я хочу отобразить дату рождения в зависимости от локали пользователя. В моем приложении одно из моих полей - это дата рождения, которая в настоящее время имеет формат dd/mm/yyyy
, Поэтому, если пользователь меняет свой язык, формат даты также должен измениться. Любые указатели или примеры кода действительно помогут мне преодолеть проблему.
8 ответов
Вы можете использовать класс DateFormat, который форматирует дату в соответствии с языковым стандартом пользователя.
Пример:
String dateOfBirth = "26/02/1974";
SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");
Date date = null;
try {
date = sdf.parse(dateOfBirth);
} catch (ParseException e) {
// handle exception here !
}
java.text.DateFormat dateFormat = android.text.format.DateFormat.getDateFormat(context);
String s = dateFormat.format(date);
Вы можете использовать разные методы getLongDateFormat
, getMediumDateFormat
в зависимости от уровня детализации вы хотели бы иметь.
Хотя принятый ответ был правильным, когда был задан вопрос, позже он устарел. Я предлагаю современный ответ.
java.time и ThreeTenABP
DateTimeFormatter dateFormatter = DateTimeFormatter.ofLocalizedDate(FormatStyle.SHORT);
LocalDate dateOfBirth = LocalDate.of(1991, Month.OCTOBER, 13);
String formattedDob = dateOfBirth.format(dateFormatter);
System.out.println("Born: " + formattedDob);
Он дает разный вывод в зависимости от настройки локали JVM (обычно берется с устройства). Например:
- Канадский французский:
Born: 91-10-13
- Китайский язык:
Born: 1991/10/13
- Немецкий:
Born: 13.10.91
- Итальянский:
Born: 13/10/91
Если вам нужен более длинный формат, вы можете указать другой стиль формата. Примеры выходных данных для локали (США) английский:
FormatStyle.SHORT
:Born: 10/13/91
FormatStyle.MEDIUM
:Born: Oct 13, 1991
FormatStyle.LONG
:Born: October 13, 1991
FormatStyle.FULL
:Born: Thursday, October 13, 1991
Вопрос: Могу ли я использовать java.time на Android?
Да, java.time прекрасно работает на старых и новых устройствах Android. Просто требуется как минимум Java 6.
- В Java 8 и новее, а также на новых устройствах Android (начиная с уровня API 26) современный API встроен.
- В Java 6 и 7 используйте ThreeTen Backport, бэкпорт современных классов (ThreeTen для JSR 310; см. Ссылки внизу).
- На (более раннем) Android используйте Android-версию ThreeTen Backport. Это называется ThreeTenABP. И убедитесь, что вы импортируете классы даты и времени из
org.threeten.bp
с подпакетами.
Вопрос: Могу ли я также принимать вводимые пользователем данные в локальном формате пользователя?
Да, ты можешь. Средство форматирования также можно использовать для разбора строки от пользователя вLocalDate
:
LocalDate date = LocalDate.parse(userInputString, dateFormatter);
Я предлагаю вам сначала отформатировать примерную дату и показать ее пользователю, чтобы он / она мог видеть, какой формат ожидает ваша программа для его / ее локали. В качестве примера даты возьмите дату с днем месяца больше 12 и годом больше 31, чтобы порядок дня, месяца и года можно было увидеть из примера (для более длинных форматов год не имеет значения, так как он будет четырехзначным.).
Разбор вызовет DateTimeParseException
если пользователь ввел дату в неправильном формате или недействительную дату. Поймайте его и позвольте пользователю попробовать еще раз.
Вопрос: Могу ли я поступить так же со временем суток? Дата и время?
Да. Для форматирования времени суток в соответствии с локалью пользователя получите средство форматирования отDateTimeFormatter.ofLocalizedTime
. Для даты и времени вместе используйте одну из перегруженных версийDateTimeFormatter.ofLocalizedDateTime
.
Избегайте классов DateFormat, SImpleDateFormat и Date
Я рекомендую вам не использовать DateFormat
, SimpleDateFormat
а также Date
. Эти классы плохо спроектированы и давно устарели, а первые два особенно неприятны. Вместо этого используйтеLocalDate
, DateTimeFormatter
и другие классы из java.time, современного API даты и времени Java.
Ссылки
- Учебник Oracle: Date Time, объясняющий, как использовать java.time.
- Запрос спецификации Java (JSR) 310, где
java.time
был впервые описан. - Проект ThreeTen Backport, то портировать из
java.time
на Java 6 и 7 (ThreeTen для JSR-310). - ThreeTenABP, версия ThreeTen Backport для Android
- Вопрос: как использовать ThreeTenABP в Android Project, с очень подробным объяснением.
Так просто как
Для даты + время:
DateFormat format = DateFormat.getDateTimeInstance(DateFormat.DEFAULT, DateFormat.SHORT, Locale.getDefault());
Для всего свидания:
DateFormat format = DateFormat.getDateInstance(DateFormat.SHORT, Locale.getDefault());
Android API обеспечивает простой способ отображения локализованного формата даты. Следующий код работает.
public class FileDateUtil {
public static String getModifiedDate(long modified) {
return getModifiedDate(Locale.getDefault(), modified);
}
public static String getModifiedDate(Locale locale, long modified) {
SimpleDateFormat dateFormat = null;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
dateFormat = new SimpleDateFormat(getDateFormat(locale));
} else {
dateFormat = new SimpleDateFormat("MMM/dd/yyyy hh:mm:ss aa");
}
return dateFormat.format(new Date(modified));
}
@TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR2)
public static String getDateFormat(Locale locale) {
return DateFormat.getBestDateTimePattern(locale, "MM/dd/yyyy hh:mm:ss aa");
}
}
Вы можете проверить следующий код.
String koreaData = FileDateUtil.getModifiedDate(Locale.KOREA, System.currentTimeMillis());
String franceData = FileDateUtil.getModifiedDate(Locale.FRENCH, System.currentTimeMillis());
String defaultData = FileDateUtil.getModifiedDate(Locale.getDefault(), System.currentTimeMillis());
String result = "Korea : " + koreaData + System.getProperty("line.separator");
result += "France : " + franceData + System.getProperty("line.separator");
result += "Default : " + defaultData + System.getProperty("line.separator");
tv.setText(result);
Чтобы изменить формат даты в соответствии с локалью, мне понадобился следующий код:
String dateOfBirth = "26/02/1974";
SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");
Date date = null;
try {
date = sdf.parse(dateOfBirth);
} catch (ParseException e) {
// handle exception here !
}
String myString = DateFormat.getDateInstance(DateFormat.SHORT).format(date);
Затем, когда вы меняете локаль, формат даты будет меняться в зависимости от нее. Для получения дополнительной информации о шаблонах дат: http://docs.oracle.com/javase/tutorial/i18n/format/dateFormat.html
Простой способ сделать это:
String AR_Format = "dd-mm-yyyy";
String EN_Format = "mm-dd-yyyy";
String getFomattedDateByLocale(Date date, String locale) {
return new SimpleDateFormat(strDateFormat, new Locale(locale)).format(date);
}
И затем назовите это так:
txtArabicDate.setText(getFomattedDateByLocale(new Date(), AR_Format));
txtEnglishDate.setText(getFomattedDateByLocale(new Date(), EN_Format));
Не забудьте заменить
new Date()
по вашей собственной переменной даты.
Удачи.
Мой способ, например: UTC iso format String to android User.
//string UTC instant to localDateTime
String example = "2022-01-27T13:04:23.891374801Z"
Instant instant = Instant.parse(example);
TimeZone timeZone = TimeZone.getDefault();
LocalDateTime localDateTime = LocalDateTime.ofInstant(instant, timeZone.toZoneId());
//localDateTime to device culture string output
DateTimeFormatter dateFormatter = DateTimeFormatter.ofLocalizedDate(FormatStyle.LONG);
String strDate = localDateTime.toLocalDate().format(dateFormatter);
DateTimeFormatter timeFormatter = DateTimeFormatter.ofLocalizedTime(FormatStyle.MEDIUM);
String strTime = localDateTime.toLocalTime().format(timeFormatter);
//strings to views
txtDate.setText(strDate);
txtTime.setText(strTime);
Чтобы получить шаблон формата даты, вы можете сделать:
Format dateFormat = android.text.format.DateFormat.getDateFormat(getApplicationContext());
String pattern = ((SimpleDateFormat) dateFormat).toLocalizedPattern();
После этого вы можете отформатировать свой ввод в соответствии с шаблоном.