Skip to content

Instantly share code, notes, and snippets.

@subchen
Created January 9, 2015 00:58
Show Gist options
  • Save subchen/2ea32c882f2d406948f8 to your computer and use it in GitHub Desktop.
Save subchen/2ea32c882f2d406948f8 to your computer and use it in GitHub Desktop.
SafeSimpleDateFormat
package jetbrick.util;
import java.text.DateFormatSymbols;
import java.text.FieldPosition;
import java.text.Format;
import java.text.NumberFormat;
import java.text.ParseException;
import java.text.ParsePosition;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.TimeZone;
/**
* This class implements a Thread-Safe (re-entrant) SimpleDateFormat
* class. It does this by using a ThreadLocal that holds a Map, instead
* of the traditional approach to hold the SimpleDateFormat in a ThreadLocal.
*
* Each ThreadLocal holds a single HashMap containing SimpleDateFormats, keyed
* by a String format (e.g. "yyyy/M/d", etc.), for each new SimpleDateFormat
* instance that was created within the threads execution context.
*/
public final class SafeSimpleDateFormat extends Format {
private static final long serialVersionUID = 1L;
private static final ThreadLocal<Map<String, SimpleDateFormat>> _dateFormats = new ThreadLocal<Map<String, SimpleDateFormat>>() {
@Override
public Map<String, SimpleDateFormat> initialValue() {
return new HashMap<String, SimpleDateFormat>();
}
};
public static SimpleDateFormat getFormatter(String format) {
Map<String, SimpleDateFormat> formatters = _dateFormats.get();
SimpleDateFormat formatter = formatters.get(format);
if (formatter == null) {
formatter = new SimpleDateFormat(format);
formatters.put(format, formatter);
}
return formatter;
}
private final String _format;
public SafeSimpleDateFormat(String format) {
_format = format;
}
@Override
public StringBuffer format(Object obj, StringBuffer toAppendTo, FieldPosition pos) {
return getFormatter(_format).format(obj, toAppendTo, pos);
}
@Override
public Object parseObject(String source, ParsePosition pos) {
return getFormatter(_format).parse(source, pos);
}
public Date parse(String day) throws ParseException {
return getFormatter(_format).parse(day);
}
public void setTimeZone(TimeZone tz) {
getFormatter(_format).setTimeZone(tz);
}
public void setCalendar(Calendar cal) {
getFormatter(_format).setCalendar(cal);
}
public void setNumberFormat(NumberFormat fmt) {
getFormatter(_format).setNumberFormat(fmt);
}
public void setLenient(boolean lenient) {
getFormatter(_format).setLenient(lenient);
}
public void setDateFormatSymbols(DateFormatSymbols symbols) {
getFormatter(_format).setDateFormatSymbols(symbols);
}
public void set2DigitYearStart(Date date) {
getFormatter(_format).set2DigitYearStart(date);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment