Index: DateUtils.java
===================================================================
--- DateUtils.java (revision 545710)
+++ DateUtils.java (working copy)
@@ -35,7 +35,6 @@
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
-import java.util.Locale;
import java.util.TimeZone;
/**
@@ -149,15 +148,10 @@
dateValue = dateValue.substring (1, dateValue.length() - 1);
}
- SimpleDateFormat dateParser = null;
for (int i = 0; i < dateFormats.length; i++) {
- if (dateParser == null) {
- dateParser = new SimpleDateFormat(dateFormats[i], Locale.US);
- dateParser.setTimeZone(TimeZone.getTimeZone("GMT"));
- dateParser.set2DigitYearStart(startDate);
- } else {
- dateParser.applyPattern(dateFormats[i]);
- }
+ SimpleDateFormat dateParser = SimpleDateFormatFactory.formatFor(dateFormats[i]);
+ dateParser.set2DigitYearStart(startDate);
+
try {
return dateParser.parse(dateValue);
} catch (ParseException pe) {
@@ -198,8 +192,7 @@
if (date == null) throw new IllegalArgumentException("date is null");
if (pattern == null) throw new IllegalArgumentException("pattern is null");
- SimpleDateFormat formatter = new SimpleDateFormat(pattern, Locale.US);
- formatter.setTimeZone(GMT);
+ SimpleDateFormat formatter = SimpleDateFormatFactory.formatFor(pattern);
return formatter.format(date);
}
Index: SimpleDateFormatFactory.java
===================================================================
--- SimpleDateFormatFactory.java
+++ SimpleDateFormatFactory.java
@@ -0,0 +1,48 @@
+package org.apache.http.util;
+
+import java.text.SimpleDateFormat;
+import java.util.HashMap;
+import java.util.Locale;
+import java.util.Map;
+import java.util.TimeZone;
+
+/**
+ * A factory for {@link SimpleDateFormat}s. The instances are stored in a
+ * threadlocal way because SimpleDateFormat is not threadsafe as noted in
+ * {@link SimpleDateFormat its javadoc}.
+ *
+ * @author Daniel Mueller
+ */
+final class SimpleDateFormatFactory {
+
+ private static final ThreadLocal threadlocalFormats = new ThreadLocal() {
+ @Override
+ protected Object initialValue() {
+ return new HashMap();
+ }
+ };
+
+ /**
+ * creates a {@link SimpleDateFormat} for the requested format string.
+ *
+ * @param dateformat
+ * a non-null format String according to
+ * {@link SimpleDateFormat}. The format is not checked against
+ * null since all paths go through
+ * {@link DateUtils}.
+ * @return the requested format. This simple dateformat should not be used
+ * to {@link SimpleDateFormat#applyPattern(String) apply} to a
+ * different pattern.
+ */
+ public static SimpleDateFormat formatFor(String pattern) {
+ Map formats = (Map) threadlocalFormats.get();
+ SimpleDateFormat format = (SimpleDateFormat) formats.get(pattern);
+ if (format == null) {
+ format = new SimpleDateFormat(pattern, Locale.US);
+ format.setTimeZone(TimeZone.getTimeZone("GMT"));
+ formats.put(pattern, format);
+ }
+
+ return format;
+ }
+}