Одним из аспектов локализации приложения является представление времени и даты в соответствии с настройками устройства. Различные страны/регионы используют разные форматы, как следствие, нужно учитывать ряд моментов.
Первая мысль, которая приходит в голову - это использование java.text.DateFormat
(и как частный случай SimpleDateFormat
):
Calendar cal = new GregorianCalendar(2013, 11, 20); DateFormat df = new SimpleDateFormat("yyyy-MM-dd"); String date = df.format(cal.getTime()); // date == "2013-12-20"
Данный подход хорошо работает, скажем, для вэб сервиса, но он совсем неприемлем для мобильных приложений. Т.к. с большой долей вероятности для конечного пользователя шаблон форматирования не является привычным. Например, не ясно когда часы(суточное время) должны быть представлены в 12-и или 24-х часовом формате.
Более правильный решение - это использовать android.text.format.DateFormat
. Класс имеет ряд методов, возвращающих шаблон представления даты/времени в соответствии с системной локалью: getDateFormat()
, getTimeFormat()
и т.д.
Calendar cal = new GregorianCalendar(2013, 11, 20); DateFormat df = android.text.format.DateFormat.getDateFormat(this); String date = df.format(cal.getTime()); // date == "12/20/2013"
Недостаток - это полное отсутствие гибкости. Скажем, что если я не хочу показывать год или наоборот - добавить день недели? Как можно догадаться, применять такое форматирование можно лишь в частном случае, когда нет жестких требований.
Мы подошли вплотную к правильному решению - DateUtils
. Класс предоставляет семейство методов formatDateTime()
и formatDateRange
, принимающие флаги в качестве параметров, указывающие, какие поля нужно включить в шаблон. Преимущество в том, что форматирование осуществляется автоматически с учетом локали пользователя, избавляя нас от обработки всех тонкостей вручную:
Calendar cal = new GregorianCalendar(2013, 11, 20); String date = DateUtils.formatDateTime(this, cal.getTimeInMillis(), DateUtils.FORMAT_SHOW_DATE); // date == "December 20" date = DateUtils.formatDateTime(this, cal.getTimeInMillis(), DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_NUMERIC_DATE | DateUtils.FORMAT_SHOW_YEAR); // date == "12/20/2013" date = DateUtils.formatDateTime(this, cal.getTimeInMillis(), DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_NUMERIC_DATE | DateUtils.FORMAT_SHOW_TIME); // date == "00:00, 12/20/2013"
DateUtils.formatDateRange()
необходим для форматирования временного диапазона(например, "Jan 5 - Feb 12"
). Может возникнуть логичный вопрос. Для чего это нужно, если можно выполнить конкатенацию двух дат с использованием formatDateTime()
? Помимо того что он проще, в опр. условиях будет выполнена оптимизация представления даты за счет уменьшения количества отображаемых полей(например, если год/месяц не меняется в рамках диапазона):
Calendar cal1 = new GregorianCalendar(2013, 11, 20); Calendar cal2 = new GregorianCalendar(2013, 11, 25); Calendar cal3 = new GregorianCalendar(2014, 0, 5); String date = DateUtils.formatDateRange(this, cal1.getTimeInMillis(), cal2.getTimeInMillis(), DateUtils.FORMAT_SHOW_DATE); // date == "December 20 - 24" date = DateUtils.formatDateRange(this, cal1.getTimeInMillis(), cal3.getTimeInMillis(), DateUtils.FORMAT_SHOW_DATE); // date == "December 20, 2013 - January 4, 2014"
Единственная вещь в formatDateRange()
на которую следует обратить внимание - округления даты. Возможно вы заметили в примере выше, что верхняя граница диапазона была округлена в меньшую сторону(до 24 декабря вместо 25-го). Это произошло из-за того, что было выполнено отсечение по суточной границе(оригинальный текст - that's because it cuts off at midnight). Если добавить миллисекунды, то диапазон будет представлен верно.
Чтобы ваше приложение правильно представляло дату/время и по прежнему имело возможность контролировать формат DateUtils
- хорошая отправная точка. Зная и умело используя флаги, можно добиться определенной гибкости.
Замечания и доп. материалы
- Примеры приведенные выше отображают дату/время с учетом текущих(моих) настроек локали. В вашем случае, отформатированные данные, могут выглядеть иначе.
- Оригинальная статья
No comments:
Post a Comment