Wednesday, February 13, 2013

Localization of date/time using Java

I recently encountered a requirement for an Android application to do the following date/time manipulation:

  • Receive a USA formatted date/time from a web service
  • Reformat the date/time for display on an Android device in the USA, Canada (French & English) and the UK
  • The display might be just the date, or the date and time
  • The year must always display 4 digits

I'm trying to avoid the use of 3rd party libraries to keep the footprint of my Android app to a minimum, but this is a surprisingly convoluted task using raw Java.  The solution I came up with involves the following steps:

  1. Convert the original USA date/time string into a Java Date using a new SimpleDateFormat
  2. Create a localized String Format pattern using a new SimpleDateFormat returned from DateFormat.getInstance
  3. Return the localized date/time string using another new SimpleDateFormat 

Here is the source code:

@SuppressLint("SimpleDateFormat")

public String getLocalizedDateAndTime(String origUsaDateTime, boolean isDateOnly, Locale dateLocale, Locale timeLocale) {

    

    Date origDate;

    try {           

        origDate = new SimpleDateFormat("MM/dd/yyyy hh:mm a", Locale.US).parse(origUsaDateTime);            

    } catch (ParseException e) {

        throw new IllegalArgumentException("The supplied Date/Time is invalid.", e);

    }

    

    String dateString, timeString;

    String datePattern = ((SimpleDateFormat) DateFormat.getDateInstance(DateFormat.SHORT, dateLocale))

        .toLocalizedPattern().replaceAll("\\byy\\b", "yyyy");

    dateString = new SimpleDateFormat(datePattern).format(origDate);

 

    if (!isDateOnly) {

        

        String timePattern = ((SimpleDateFormat) DateFormat.getTimeInstance(DateFormat.SHORT, timeLocale))

            .toLocalizedPattern();

        timeString = " " + new SimpleDateFormat(timePattern).format(origDate);

    }

    else timeString = "";

            

    return dateString + timeString;     

}

 

I provide separate Locale instances for date and time because this process throws an invalid format exception for Locale.CANADA_FRENCH when attempting to generate the dateString value.  The  line:

String datePattern = ((SimpleDateFormat) DateFormat.getDateInstance(DateFormat.SHORT, dateLocale))

    .toLocalizedPattern().replaceAll("\\byy\\b", "yyyy");

 
returns an invalid pattern String for CANADA_FRENCH so for this particular scenario I can provide Locale.CANADA for the date and Locale.CANADA_FRENCH for the time.

 


1 comment:

  1. You should consider using this online tool for managing your software strings, if you want to save yourself some time: https://poeditor.com/

    ReplyDelete