SimpleDateFormat is not so Simple

September 22, 2007

I came across this blog Another Code Treasure today. It provides an example of a poorly written method to validate a date and then provides a better alternative. Here is the better alternative provided in the blog:

private static SimpleDateFormat mySpanishDateFormatter =
             new SimpleDateFormat("ddMMMyyyy", new Locale("es"));
    
public static boolean isSpanishDateStringValid(String dateStr) {
        if(dateStr==null)
           return false;
        mySpanishDateFormatter.setLenient(false);
        try {
             mySpanishDateFormatter.parse(dateStr);
             return true;
        } catch (ParseException e) {
            return false;
        }
}

This code is fine as long as you have a single-threaded application. But what happens if you have a mutlti-threaded application? The answer is we don’t know because SimpleDateFormat is not thread-safe. The code above will likely cause an exception to be thrown. The fix is to store the SimpleDateFormat in a ThreadLocal variable. This way each Thread gets its’ own instance of the SimpleDateFormatter. Here is an example of a Thread-Safe implementation of the date validation code:

private final ThreadLocal threadLocalFormat = 
    new ThreadLocal();

private DateFormat getDateFormat() {
        if (threadLocalFormat.get() == null) {
            threadLocalFormat.set(new SimpleDateFormat("ddMMMyyyy", new Locale("es")));
        }
        return threadLocalFormat.get();
}

public static boolean isSpanishDateStringValid(String dateStr) {
        if(dateStr==null)
           return false;
        getDateFormat().setLenient(false);
        try {
             getDateFormat().parse(dateStr);
             return true;
        } catch (ParseException e) {
            return false;
        }
}
Advertisements