package org.marketcetera.core;
import java.text.SimpleDateFormat;
import java.util.Locale;
import java.util.TimeZone;
/**
* Because {@link SimpleDateFormat} is not threadsafe, this class provides
* a simple alternative to explicit synchronization. This subclass of
* {@link ThreadLocal} will create an instance of SimpleDateFormat
* for each thread that accesses the variable.
*
* For convenience parallel constructors are provided for each form
* of the SimpleDateFormat constructor.
*
* The implementation of {@link #initialValue()} provides the
* instance of SimpleDateFormat for each thread.
*
* @author gmiller
*
*/
public class ThreadLocalSimpleDateFormat extends ThreadLocal<SimpleDateFormat> {
private final String formatString;
private final Locale locale;
private TimeZone timeZone;
/**
* Constructor that invokes the String construtor of SimpleDateFormat
* on each accessing thread.
*
* @exception NullPointerException if the given pattern is null
* @exception IllegalArgumentException if the given pattern is invalid
* @see SimpleDateFormat#SimpleDateFormat(String)
*/
public ThreadLocalSimpleDateFormat(String formatString) {
this(formatString, null);
}
/**
* Constructor that invokes the (String, Locale) constructor
* on each accessing thread.
*
* @exception NullPointerException if the given pattern is null
* @exception IllegalArgumentException if the given pattern is invalid
* @see SimpleDateFormat#SimpleDateFormat(String, Locale)
*/
public ThreadLocalSimpleDateFormat(String formatString, Locale locale) {
this.formatString = formatString;
this.locale = locale;
new SimpleDateFormat(formatString);
}
@Override
protected SimpleDateFormat initialValue() { //i18n_datetime
SimpleDateFormat simpleDateFormat;
if (locale != null){
simpleDateFormat = new SimpleDateFormat(formatString, locale);
} else {
simpleDateFormat = new SimpleDateFormat(formatString);
}
if (timeZone != null){
simpleDateFormat.setTimeZone(timeZone);
}
return simpleDateFormat;
}
/**
* Sets the timeZone string that will be set on each
* instance of SimpleDateFormat created by this object.
*
* @param timeZone the time zone as a string
* @see SimpleDateFormat#setTimeZone(TimeZone)
*/
public void setTimeZone(TimeZone timeZone) {
this.timeZone = timeZone;
}
}