5
\$\begingroup\$

I have the following code for taking a date in the form of a string yyyy-MM-dd HH:mm:ss (UTC timezone) and turning it into EEEE d(st, nd, rd, th) MMMM yyyy HH:mm (devices default timezone).

However, my problem with the way I have done it is the code looks messy and inefficient. Is there a way to achieve what I want without formating and parsing the same date so many times to make it more efficient? Or any other improvements?

Preferably supporting Android API level 14.


String inputExample = "2017-06-28 22:44:55";

//Converts UTC to Device Default (Local)
private String convertUTC(String dateStr) {
    try {
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        df.setTimeZone(TimeZone.getTimeZone("UTC"));
        Date temp = df.parse(dateStr);
        df.setTimeZone(TimeZone.getDefault());
        String local = df.format(temp);
        Date localDate = df.parse(dateStr);
        SimpleDateFormat outputDF1 = new SimpleDateFormat("EEEE ");
        SimpleDateFormat outputDF2 = new SimpleDateFormat(" MMMM yyyy HH:mm");
        return outputDF1.format(temp) + prefix(local) + outputDF2.format(temp);
    } catch(java.text.ParseException pE) {
        Log.e("", "Parse Exception", pE);
        return null;
    }
}

private String prefix(String dateStr) {
    try {
        SimpleDateFormat outputDF = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date temp = outputDF.parse(dateStr);
        SimpleDateFormat df = new SimpleDateFormat("d");
        int d = Integer.parseInt(df.format(temp));
        if(1 <= d && d <= 31) {
            if(11 <= d && d <= 13)
                return d + "th";
            switch (d % 10) {
                case 1: return d + "st";
                case 2: return d + "nd";
                case 3: return d + "rd";
                default: return d + "th";
            }
        }
        Log.e("", "Null Date");
        return null;
    } catch(java.text.ParseException pE) {
        Log.e("", "Parse Exception", pE);
        return null;
    }
}
\$\endgroup\$
2
\$\begingroup\$

Parsing twice

Instead of parsing dateStr twice, consider passing the Date object you have already constructed to the local time zone into prefix(String).

Calendar vs Date

A Calendar object has arguably better semantics than a Date, so it may be easier to access the individual chronological fields (actually, in your case, just the day component).

Lengthy try-catch block

Your try-catch block in convertUTC(String) spans the entirety of the method, but it's generally recommended to keep them short and to-the-point so that you effectively get a fail-fast mechanism. It's also easier to understand what's the exact code that might plausibly throw the checked Exception, so that it can be easier to refactor in the future.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.