Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Format date to local setting but only for month and day

Tags:

date

android

My date is in a string in the format "2013-12-31". I want to convert this to a local date based upon the user's device setting but only show the month and day. So if the user's device is set to German, the date should be converted to "31.12". In Germany, the day comes first followed by the month. I don't want the year to be included.

like image 620
Johann Avatar asked Oct 22 '13 14:10

Johann


3 Answers

For Build.VERSION.SDK_INT < 18 I could not find a way to obtain a month/day format that obeys user preferences. This answer works if you are willing to accept month/day in user's locale default pattern (not their preferred order or format). My implementation uses the full numeric format in versions less than 18 or if any issues are encountered in the following carefully programmed series of steps.

  1. Get user's numeric date format pattern as String
  2. Reduce pattern to skeleton format without symbols or years
  3. Obtain localized month/day format with DateFormat.getBestDateTimePattern
  4. Reorder localized month/day format according to user preferred order. (key assumption: days and months can be naively swapped for all localized numeric formats)

This should result in a month/day pattern that obeys user's preference in localized formatting.


Get user date pattern string per this answer:

java.text.DateFormat shortDateFormat = DateFormat.getDateFormat(context);
if (shortDateFormat instanceof SimpleDateFormat) {
    String textPattern = ((SimpleDateFormat) shortDateFormat).toPattern();
}

Reduce pattern to day/month skeleton by removing all characters not 'd' or 'M', example result:

String skeletonPattern = 'ddMM'

Get localized month/day format:

String workingFormat = DateFormat.getBestDateTimePattern(Locale.getDefault(), skeletonPattern);

(note: this method requires api 18 and above and does not return values in user-preferred order or format, hence this long-winded answer):

Get user preferred date order ('M', 'd', 'y') from this method:

char[] order = DateFormat.getDateFormatOrder(context);

(note: I suppose you could parse the original pattern to get this information too)


If workingFormat is in the correct order, your job is finished. Otherwise, switch the 'd's and the 'M's in the pattern. The key assumption here is that days and months can be naively swapped for all localized numeric formats.

DateFormat monthDayFormat = new SimpleDateFormat(workingFormat);
like image 154
Rich Ehmer Avatar answered Oct 13 '22 19:10

Rich Ehmer


I think, this is the simplest solution for apps targeting API > 17:

dateFormat = SimpleDateFormat(DateFormat.getBestDateTimePattern(Locale.getDefault(), "MMMM dd"), Locale.getDefault())
like image 36
a.ch. Avatar answered Oct 13 '22 21:10

a.ch.


A bit late, bit I also faced the same issue. That is how I solved it:

String dayMonthDateString = getDayMonthDateString("2010-12-31", "yyyy-MM-dd", Locale.GERMANY);
Log.i("customDate", "dayMonthDateString = " + dayMonthDateString);


private String getDayMonthDateString(String dateString, String dateFormatString, Locale locale)
{
    try
    {
        boolean dayBeforeMonth = defineDayMonthOrder(locale);

        String calendarDate = dateString;
        SimpleDateFormat dateFormat = new SimpleDateFormat(dateFormatString);
        Date date = dateFormat.parse(calendarDate);

        SimpleDateFormat newDateFormat;

        if (dayBeforeMonth)
        {
            newDateFormat = new SimpleDateFormat("dd.MM", locale);
        }
        else
        {
            newDateFormat = new SimpleDateFormat("MM.dd", locale);
        }

        return newDateFormat.format(date);
    }
    catch (ParseException e)
    {
        e.printStackTrace();
    }

    return null;
}


private boolean defineDayMonthOrder(Locale locale) throws ParseException
{
    String day = "10";
    String month = "11";
    String year = "12";

    String calendarDate = day + "." + month + "." + year;

    SimpleDateFormat format = new SimpleDateFormat("dd.MM.yy");
    Date date = format.parse(calendarDate);

    String localizedDate = SimpleDateFormat.getDateInstance(SimpleDateFormat.SHORT, locale).format(date);

    int indexOfDay = localizedDate.indexOf(day);
    int indexOfMonth = localizedDate.indexOf(month);

    return indexOfDay < indexOfMonth ? true : false;
}

Let me know of any questions you could have related to the solution.

like image 38
Ayaz Alifov Avatar answered Oct 13 '22 20:10

Ayaz Alifov