BasicAccumulator
manages the ValueCounters and Expressions without regard to Facets.
*/
@@ -143,7 +141,7 @@ public class BasicAccumulator extends ValueAccumulator {
if (expressionName.equals(expressionNames[count])) {
Comparable value = expressions[count].getValue();
if (value.getClass().equals(Date.class)) {
- return DateFormatUtil.formatExternal((Date)value);
+ return ((Date)value).toInstant().toString();
} else {
return value.toString();
}
diff --git a/solr/contrib/analytics/src/java/org/apache/solr/analytics/accumulator/FacetingAccumulator.java b/solr/contrib/analytics/src/java/org/apache/solr/analytics/accumulator/FacetingAccumulator.java
index 7cb0c144ea2..03392f0ef1a 100644
--- a/solr/contrib/analytics/src/java/org/apache/solr/analytics/accumulator/FacetingAccumulator.java
+++ b/solr/contrib/analytics/src/java/org/apache/solr/analytics/accumulator/FacetingAccumulator.java
@@ -30,6 +30,7 @@ import java.util.Map.Entry;
import java.util.Set;
import java.util.TreeMap;
+import com.google.common.collect.Iterables;
import org.apache.lucene.index.LeafReaderContext;
import org.apache.lucene.search.BooleanClause.Occur;
import org.apache.lucene.search.BooleanQuery;
@@ -60,9 +61,6 @@ import org.apache.solr.search.Filter;
import org.apache.solr.search.QParser;
import org.apache.solr.search.SolrIndexSearcher;
import org.apache.solr.search.SyntaxError;
-import org.apache.solr.util.DateFormatUtil;
-
-import com.google.common.collect.Iterables;
/**
* A FacetingAccumulator
manages the StatsCollectors and Expressions for facets.
@@ -376,7 +374,7 @@ public class FacetingAccumulator extends BasicAccumulator implements FacetValueA
if (expressionName.equals(expressionNames[count])) {
Comparable value = facetExpressions[count].getValue();
if (value.getClass().equals(Date.class)) {
- return DateFormatUtil.formatExternal((Date)value);
+ return ((Date)value).toInstant().toString();
} else {
return value.toString();
}
@@ -430,7 +428,7 @@ public class FacetingAccumulator extends BasicAccumulator implements FacetValueA
if (expressionName.equals(expressionNames[count])) {
Comparable value = facetExpressions[count].getValue();
if (value.getClass().equals(Date.class)) {
- return DateFormatUtil.formatExternal((Date)value);
+ return ((Date)value).toInstant().toString();
} else {
return value.toString();
}
diff --git a/solr/contrib/analytics/src/java/org/apache/solr/analytics/expression/ExpressionFactory.java b/solr/contrib/analytics/src/java/org/apache/solr/analytics/expression/ExpressionFactory.java
index 8ad4070d180..1f2d0e04b25 100644
--- a/solr/contrib/analytics/src/java/org/apache/solr/analytics/expression/ExpressionFactory.java
+++ b/solr/contrib/analytics/src/java/org/apache/solr/analytics/expression/ExpressionFactory.java
@@ -16,7 +16,6 @@
*/
package org.apache.solr.analytics.expression;
-import java.text.ParseException;
import java.util.ArrayList;
import java.util.List;
@@ -24,7 +23,7 @@ import org.apache.solr.analytics.statistics.StatsCollector;
import org.apache.solr.analytics.util.AnalyticsParams;
import org.apache.solr.common.SolrException;
import org.apache.solr.common.SolrException.ErrorCode;
-import org.apache.solr.util.DateFormatUtil;
+import org.apache.solr.util.DateMathParser;
public class ExpressionFactory {
@@ -81,11 +80,7 @@ public class ExpressionFactory {
throw new SolrException(ErrorCode.BAD_REQUEST, "The constant "+operands+" cannot be converted into a number.",e);
}
} else if (topOperation.equals(AnalyticsParams.CONSTANT_DATE)) {
- try {
- return new ConstantDateExpression(DateFormatUtil.parseDate(operands));
- } catch (ParseException e) {
- throw new SolrException(ErrorCode.BAD_REQUEST, "The constant "+operands+" cannot be converted into a date.",e);
- }
+ return new ConstantDateExpression(DateMathParser.parseMath(null, operands));
} else if (topOperation.equals(AnalyticsParams.CONSTANT_STRING)) {
operands = expression.substring(paren+1, expression.lastIndexOf(')'));
return new ConstantStringExpression(operands);
diff --git a/solr/contrib/analytics/src/java/org/apache/solr/analytics/statistics/StatsCollectorSupplierFactory.java b/solr/contrib/analytics/src/java/org/apache/solr/analytics/statistics/StatsCollectorSupplierFactory.java
index bee7431a69d..bd9f65d2427 100644
--- a/solr/contrib/analytics/src/java/org/apache/solr/analytics/statistics/StatsCollectorSupplierFactory.java
+++ b/solr/contrib/analytics/src/java/org/apache/solr/analytics/statistics/StatsCollectorSupplierFactory.java
@@ -17,16 +17,14 @@
package org.apache.solr.analytics.statistics;
import java.lang.invoke.MethodHandles;
-import java.text.ParseException;
import java.util.ArrayList;
-import java.util.HashMap;
import java.util.HashSet;
-import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
+import com.google.common.base.Supplier;
import org.apache.lucene.queries.function.ValueSource;
import org.apache.lucene.queries.function.valuesource.BytesRefFieldSource;
import org.apache.lucene.queries.function.valuesource.DoubleFieldSource;
@@ -36,7 +34,6 @@ import org.apache.lucene.queries.function.valuesource.LongFieldSource;
import org.apache.solr.analytics.expression.ExpressionFactory;
import org.apache.solr.analytics.request.ExpressionRequest;
import org.apache.solr.analytics.util.AnalyticsParams;
-import org.apache.solr.analytics.util.AnalyticsParsers;
import org.apache.solr.analytics.util.valuesource.AbsoluteValueDoubleFunction;
import org.apache.solr.analytics.util.valuesource.AddDoubleFunction;
import org.apache.solr.analytics.util.valuesource.ConcatStringFunction;
@@ -67,12 +64,10 @@ import org.apache.solr.schema.TrieDoubleField;
import org.apache.solr.schema.TrieFloatField;
import org.apache.solr.schema.TrieIntField;
import org.apache.solr.schema.TrieLongField;
-import org.apache.solr.util.DateFormatUtil;
+import org.apache.solr.util.DateMathParser;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import com.google.common.base.Supplier;
-
public class StatsCollectorSupplierFactory {
private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
@@ -443,11 +438,7 @@ public class StatsCollectorSupplierFactory {
throw new SolrException(ErrorCode.BAD_REQUEST,"The filter value "+arguments[1]+" cannot be converted into an integer.",e);
}
} else if ( src instanceof DateFieldSource || src instanceof MultiDateFunction) {
- try {
- defaultObject = DateFormatUtil.parseDate(arguments[1]);
- } catch (ParseException e) {
- throw new SolrException(ErrorCode.BAD_REQUEST,"The filter value "+arguments[1]+" cannot be converted into a date.",e);
- }
+ defaultObject = DateMathParser.parseMath(null, arguments[1]);
} else if ( src instanceof LongFieldSource ) {
try {
defaultObject = new Long(arguments[1]);
@@ -578,11 +569,7 @@ public class StatsCollectorSupplierFactory {
if (arguments.length!=1) {
throw new SolrException(ErrorCode.BAD_REQUEST,"The constant date declaration ["+expressionString+"] does not have exactly 1 argument.");
}
- try {
- return new ConstDateSource(DateFormatUtil.parseDate(operands));
- } catch (ParseException e) {
- throw new SolrException(ErrorCode.BAD_REQUEST,"The constant "+operands+" cannot be converted into a date.",e);
- }
+ return new ConstDateSource(DateMathParser.parseMath(null, operands));
} else if (operation.equals(AnalyticsParams.FILTER)) {
return buildFilterSource(schema, operands, DATE_TYPE);
}
diff --git a/solr/contrib/analytics/src/java/org/apache/solr/analytics/util/AnalyticsParsers.java b/solr/contrib/analytics/src/java/org/apache/solr/analytics/util/AnalyticsParsers.java
index dad4a5b28d4..7a7e697d059 100644
--- a/solr/contrib/analytics/src/java/org/apache/solr/analytics/util/AnalyticsParsers.java
+++ b/solr/contrib/analytics/src/java/org/apache/solr/analytics/util/AnalyticsParsers.java
@@ -17,8 +17,8 @@
package org.apache.solr.analytics.util;
import java.io.IOException;
+import java.time.Instant;
import java.util.Arrays;
-import java.util.Date;
import org.apache.lucene.util.BytesRef;
import org.apache.lucene.util.LegacyNumericUtils;
@@ -29,7 +29,6 @@ import org.apache.solr.schema.TrieDoubleField;
import org.apache.solr.schema.TrieFloatField;
import org.apache.solr.schema.TrieIntField;
import org.apache.solr.schema.TrieLongField;
-import org.apache.solr.util.DateFormatUtil;
/**
* Class to hold the parsers used for Solr Analytics.
@@ -149,7 +148,7 @@ public class AnalyticsParsers {
@SuppressWarnings("deprecation")
public String parse(BytesRef bytes) throws IOException {
try {
- return DateFormatUtil.formatExternal(new Date(LegacyNumericUtils.prefixCodedToLong(bytes)));
+ return Instant.ofEpochMilli(LegacyNumericUtils.prefixCodedToLong(bytes)).toString();
} catch (NumberFormatException e) {
throw new IOException("The byte array "+Arrays.toString(bytes.bytes)+" cannot be converted to a date.");
}
@@ -157,7 +156,7 @@ public class AnalyticsParsers {
@SuppressWarnings("deprecation")
@Override
public String parseNum(long l) {
- return ""+DateFormatUtil.formatExternal(new Date(l));
+ return Instant.ofEpochMilli(l).toString();
}
};
diff --git a/solr/contrib/analytics/src/java/org/apache/solr/analytics/util/RangeEndpointCalculator.java b/solr/contrib/analytics/src/java/org/apache/solr/analytics/util/RangeEndpointCalculator.java
index 6d899e0b9cd..fa9686d6785 100644
--- a/solr/contrib/analytics/src/java/org/apache/solr/analytics/util/RangeEndpointCalculator.java
+++ b/solr/contrib/analytics/src/java/org/apache/solr/analytics/util/RangeEndpointCalculator.java
@@ -31,7 +31,6 @@ import org.apache.solr.schema.SchemaField;
import org.apache.solr.schema.TrieDateField;
import org.apache.solr.schema.TrieField;
import org.apache.solr.util.DateMathParser;
-import org.apache.solr.util.DateFormatUtil;
public abstract class RangeEndpointCalculatorConstDateSource
returns a constant date for all documents
@@ -35,7 +34,7 @@ import org.apache.solr.util.DateFormatUtil;
public class ConstDateSource extends ConstDoubleSource {
public final static String NAME = AnalyticsParams.CONSTANT_DATE;
- public ConstDateSource(Date constant) throws ParseException {
+ public ConstDateSource(Date constant) {
super(constant.getTime());
}
@@ -46,7 +45,7 @@ public class ConstDateSource extends ConstDoubleSource {
@SuppressWarnings("deprecation")
@Override
public String description() {
- return name()+"(" + DateFormatUtil.formatExternal(new Date(getLong())) + ")";
+ return name()+"(" + Instant.ofEpochMilli(getLong()) + ")";
}
protected String name() {
@@ -83,7 +82,7 @@ public class ConstDateSource extends ConstDoubleSource {
@SuppressWarnings("deprecation")
@Override
public String strVal(int doc) {
- return DateFormatUtil.formatExternal(new Date(longVal(doc)));
+ return Instant.ofEpochMilli(longVal(doc)).toString();
}
@Override
public boolean boolVal(int doc) {
diff --git a/solr/contrib/analytics/src/java/org/apache/solr/analytics/util/valuesource/DateFieldSource.java b/solr/contrib/analytics/src/java/org/apache/solr/analytics/util/valuesource/DateFieldSource.java
index 631aca0b63e..4d66e0025bc 100644
--- a/solr/contrib/analytics/src/java/org/apache/solr/analytics/util/valuesource/DateFieldSource.java
+++ b/solr/contrib/analytics/src/java/org/apache/solr/analytics/util/valuesource/DateFieldSource.java
@@ -17,11 +17,12 @@
package org.apache.solr.analytics.util.valuesource;
import java.io.IOException;
+import java.time.Instant;
import java.util.Date;
import java.util.Map;
-import org.apache.lucene.index.LeafReaderContext;
import org.apache.lucene.index.DocValues;
+import org.apache.lucene.index.LeafReaderContext;
import org.apache.lucene.index.NumericDocValues;
import org.apache.lucene.queries.function.FunctionValues;
import org.apache.lucene.queries.function.docvalues.LongDocValues;
@@ -31,7 +32,6 @@ import org.apache.lucene.util.BytesRef;
import org.apache.lucene.util.LegacyNumericUtils;
import org.apache.lucene.util.mutable.MutableValue;
import org.apache.lucene.util.mutable.MutableValueDate;
-import org.apache.solr.util.DateFormatUtil;
/**
* Extends {@link LongFieldSource} to have a field source that takes in
@@ -53,7 +53,7 @@ public class DateFieldSource extends LongFieldSource {
@SuppressWarnings("deprecation")
public String longToString(long val) {
- return DateFormatUtil.formatExternal((Date)longToObject(val));
+ return Instant.ofEpochMilli(val).toString();
}
@Override
diff --git a/solr/contrib/analytics/src/java/org/apache/solr/analytics/util/valuesource/FilterFieldSource.java b/solr/contrib/analytics/src/java/org/apache/solr/analytics/util/valuesource/FilterFieldSource.java
index 8eb35d144c3..22f5a572076 100644
--- a/solr/contrib/analytics/src/java/org/apache/solr/analytics/util/valuesource/FilterFieldSource.java
+++ b/solr/contrib/analytics/src/java/org/apache/solr/analytics/util/valuesource/FilterFieldSource.java
@@ -25,7 +25,6 @@ import org.apache.lucene.queries.function.FunctionValues;
import org.apache.lucene.queries.function.ValueSource;
import org.apache.lucene.util.mutable.MutableValue;
import org.apache.solr.analytics.util.AnalyticsParams;
-import org.apache.solr.util.DateFormatUtil;
/**
* DefaultIsMissingFieldSource
wraps a field source to return missing values
@@ -49,7 +48,7 @@ public class FilterFieldSource extends ValueSource {
@Override
public String description() {
if (missValue.getClass().equals(Date.class)) {
- return name()+"("+source.description()+","+DateFormatUtil.formatExternal((Date)missValue)+")";
+ return name()+"("+source.description()+","+ ((Date)missValue).toInstant() +")";
} else {
return name()+"("+source.description()+","+missValue.toString()+")";
}
diff --git a/solr/contrib/analytics/src/test/org/apache/solr/analytics/expression/ExpressionTest.java b/solr/contrib/analytics/src/test/org/apache/solr/analytics/expression/ExpressionTest.java
index 25193588f6a..4a3276b9ce2 100644
--- a/solr/contrib/analytics/src/test/org/apache/solr/analytics/expression/ExpressionTest.java
+++ b/solr/contrib/analytics/src/test/org/apache/solr/analytics/expression/ExpressionTest.java
@@ -16,22 +16,22 @@
*/
package org.apache.solr.analytics.expression;
-import com.google.common.collect.ObjectArrays;
+import java.io.FileNotFoundException;
+import java.io.InputStream;
+import java.time.Instant;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.Scanner;
+import com.google.common.collect.ObjectArrays;
import org.apache.lucene.util.IOUtils;
import org.apache.solr.SolrTestCaseJ4;
import org.apache.solr.analytics.AbstractAnalyticsStatsTest;
import org.apache.solr.request.SolrQueryRequest;
import org.apache.solr.util.DateMathParser;
-import org.apache.solr.util.DateFormatUtil;
import org.junit.BeforeClass;
import org.junit.Test;
-import java.io.FileNotFoundException;
-import java.io.InputStream;
-import java.util.ArrayList;
-import java.util.Scanner;
-
public class ExpressionTest extends AbstractAnalyticsStatsTest {
private static final String fileName = "/analytics/requestFiles/expressions.txt";
@@ -156,20 +156,19 @@ public class ExpressionTest extends AbstractAnalyticsStatsTest {
assertEquals(getRawResponse(), 10, result, 0.0);
}
- @SuppressWarnings("deprecation")
@Test
public void dateMathTest() throws Exception {
String math = (String) getStatResult("dmr", "cme", VAL_TYPE.STRING);
- DateMathParser date = new DateMathParser();
- date.setNow(DateFormatUtil.parseDate((String) getStatResult("dmr", "median", VAL_TYPE.DATE)));
+ DateMathParser dateMathParser = new DateMathParser();
+ dateMathParser.setNow(new Date(Instant.parse((String) getStatResult("dmr", "median", VAL_TYPE.DATE)).toEpochMilli()));
String dateMath = (String) getStatResult("dmr", "dmme", VAL_TYPE.DATE);
- assertEquals(getRawResponse(), DateFormatUtil.parseDate(dateMath), date.parseMath(math));
+ assertEquals(getRawResponse(), new Date(Instant.parse(dateMath).toEpochMilli()), dateMathParser.parseMath(math));
math = (String) getStatResult("dmr", "cma", VAL_TYPE.STRING);
- date = new DateMathParser();
- date.setNow(DateFormatUtil.parseDate((String) getStatResult("dmr", "max", VAL_TYPE.DATE)));
+ dateMathParser = new DateMathParser();
+ dateMathParser.setNow(new Date(Instant.parse((String) getStatResult("dmr", "max", VAL_TYPE.DATE)).toEpochMilli()));
dateMath = (String) getStatResult("dmr", "dmma", VAL_TYPE.DATE);
- assertEquals(getRawResponse(), DateFormatUtil.parseDate(dateMath), date.parseMath(math));
+ assertEquals(getRawResponse(), new Date(Instant.parse(dateMath).toEpochMilli()), dateMathParser.parseMath(math));
}
@Test
diff --git a/solr/core/src/java/org/apache/solr/core/SolrDeletionPolicy.java b/solr/core/src/java/org/apache/solr/core/SolrDeletionPolicy.java
index 24b0e610d30..c7a668908ca 100644
--- a/solr/core/src/java/org/apache/solr/core/SolrDeletionPolicy.java
+++ b/solr/core/src/java/org/apache/solr/core/SolrDeletionPolicy.java
@@ -15,16 +15,6 @@
* limitations under the License.
*/
package org.apache.solr.core;
-import org.apache.lucene.index.IndexCommit;
-import org.apache.lucene.index.IndexDeletionPolicy;
-import org.apache.lucene.store.Directory;
-import org.apache.lucene.store.FSDirectory;
-import org.apache.solr.common.util.NamedList;
-import org.apache.solr.util.DateMathParser;
-import org.apache.solr.util.DateFormatUtil;
-import org.apache.solr.util.plugin.NamedListInitializedPlugin;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
import java.io.File;
import java.io.IOException;
@@ -32,6 +22,16 @@ import java.lang.invoke.MethodHandles;
import java.util.List;
import java.util.Locale;
+import org.apache.lucene.index.IndexCommit;
+import org.apache.lucene.index.IndexDeletionPolicy;
+import org.apache.lucene.store.Directory;
+import org.apache.lucene.store.FSDirectory;
+import org.apache.solr.common.util.NamedList;
+import org.apache.solr.util.DateMathParser;
+import org.apache.solr.util.plugin.NamedListInitializedPlugin;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
/**
* Standard Solr deletion policy that allows reserving index commit points
@@ -174,7 +174,7 @@ public class SolrDeletionPolicy extends IndexDeletionPolicy implements NamedList
try {
if (maxCommitAge != null) {
if (maxCommitAgeTimeStamp==-1) {
- DateMathParser dmp = new DateMathParser(DateFormatUtil.UTC, Locale.ROOT);
+ DateMathParser dmp = new DateMathParser(DateMathParser.UTC, Locale.ROOT);
maxCommitAgeTimeStamp = dmp.parseMath(maxCommitAge).getTime();
}
if (IndexDeletionPolicyWrapper.getCommitTimestamp(commit) < maxCommitAgeTimeStamp) {
diff --git a/solr/core/src/java/org/apache/solr/handler/CdcrReplicatorState.java b/solr/core/src/java/org/apache/solr/handler/CdcrReplicatorState.java
index d0b1c4a1152..9e01f117b67 100644
--- a/solr/core/src/java/org/apache/solr/handler/CdcrReplicatorState.java
+++ b/solr/core/src/java/org/apache/solr/handler/CdcrReplicatorState.java
@@ -16,17 +16,24 @@
*/
package org.apache.solr.handler;
+import java.io.IOException;
+import java.lang.invoke.MethodHandles;
+import java.time.Instant;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+
import org.apache.solr.client.solrj.impl.CloudSolrClient;
import org.apache.solr.update.CdcrUpdateLog;
import org.apache.solr.update.UpdateLog;
-import org.apache.solr.util.DateFormatUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import java.io.IOException;
-import java.lang.invoke.MethodHandles;
-import java.util.*;
-
/**
* The state of the replication with a target cluster.
*/
@@ -133,7 +140,7 @@ class CdcrReplicatorState {
Iterator
* Update Processor Factory for managing automatic "expiration" of documents.
@@ -404,7 +400,7 @@ public final class DocExpirationUpdateProcessorFactory
try {
DeleteUpdateCommand del = new DeleteUpdateCommand(req);
del.setQuery("{!cache=false}" + expireField + ":[* TO " +
- DateFormatUtil.formatExternal(SolrRequestInfo.getRequestInfo().getNOW())
+ SolrRequestInfo.getRequestInfo().getNOW().toInstant()
+ "]");
proc.processDelete(del);
diff --git a/solr/core/src/java/org/apache/solr/util/DateFormatUtil.java b/solr/core/src/java/org/apache/solr/util/DateFormatUtil.java
deleted file mode 100644
index b4e33be60ec..00000000000
--- a/solr/core/src/java/org/apache/solr/util/DateFormatUtil.java
+++ /dev/null
@@ -1,245 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.solr.util;
-
-import java.text.DateFormat;
-import java.text.DecimalFormat;
-import java.text.DecimalFormatSymbols;
-import java.text.FieldPosition;
-import java.text.NumberFormat;
-import java.text.ParseException;
-import java.text.ParsePosition;
-import java.text.SimpleDateFormat;
-import java.util.Date;
-import java.util.Locale;
-import java.util.TimeZone;
-
-import org.apache.solr.common.SolrException;
-import org.apache.solr.common.util.DateUtil;
-import org.apache.solr.request.SolrQueryRequest;
-
-public final class DateFormatUtil {
-
- public static final TimeZone UTC = TimeZone.getTimeZone("UTC");
- /**
- * Fixed TimeZone (UTC) needed for parsing/formatting Dates in the
- * canonical representation.
- */
- public static final TimeZone CANONICAL_TZ = UTC;
- /**
- * Fixed Locale needed for parsing/formatting Milliseconds in the
- * canonical representation.
- */
- public static final Locale CANONICAL_LOCALE = Locale.ROOT;
- public static final String NOW = "NOW";
- public static final char Z = 'Z';
-
- private static final ISO8601CanonicalDateFormat FORMAT_PROTOTYPE = new ISO8601CanonicalDateFormat();
-
- /**
- * Thread safe DateFormat that can format in the canonical
- * ISO8601 date format, not including the trailing "Z" (since it is
- * left off in the internal indexed values)
- */
- public final static ThreadLocal