From c3887b351e77ab6d23ddd662564b3d0d977895e4 Mon Sep 17 00:00:00 2001 From: David Smiley Date: Tue, 7 Aug 2018 11:51:16 -0400 Subject: [PATCH] SOLR-12586: Change ParseDateFieldUpdateProcessorFactory to use java.time.DateTimeFormatter, not Joda Time. Note: slightly different pattern language! Remove Joda Time. Closes #428 --- lucene/ivy-versions.properties | 1 - solr/CHANGES.txt | 10 + .../collection1/conf/solrconfig.xml | 20 +- solr/core/ivy.xml | 1 - .../apache/solr/core/ConfigSetService.java | 7 +- .../ParseDateFieldUpdateProcessorFactory.java | 82 +++++-- ...-schema-fields-update-processor-chains.xml | 20 +- ...config-parsing-update-processor-chains.xml | 49 ++--- .../conf/solrconfig-schemaless.xml | 20 +- .../configsets/_default/conf/solrconfig.xml | 20 +- ...chemaFieldsUpdateProcessorFactoryTest.java | 23 +- .../ParsingFieldUpdateProcessorsTest.java | 157 +++++++------- solr/example/files/conf/solrconfig.xml | 20 +- solr/licenses/joda-time-2.2.jar.sha1 | 1 - solr/licenses/joda-time-LICENSE-ASL.txt | 202 ------------------ solr/licenses/joda-time-NOTICE.txt | 5 - .../configsets/_default/conf/solrconfig.xml | 20 +- solr/solr-ref-guide/src/schemaless-mode.adoc | 20 +- 18 files changed, 218 insertions(+), 460 deletions(-) delete mode 100644 solr/licenses/joda-time-2.2.jar.sha1 delete mode 100644 solr/licenses/joda-time-LICENSE-ASL.txt delete mode 100644 solr/licenses/joda-time-NOTICE.txt diff --git a/lucene/ivy-versions.properties b/lucene/ivy-versions.properties index 3a1ef2b58d3..d7141bd3899 100644 --- a/lucene/ivy-versions.properties +++ b/lucene/ivy-versions.properties @@ -77,7 +77,6 @@ io.prometheus.version = 0.2.0 /javax.activation/activation = 1.1.1 /javax.servlet/javax.servlet-api = 3.1.0 -/joda-time/joda-time = 2.2 /junit/junit = 4.10 /mecab/mecab-ipadic = 2.7.0-20070801 diff --git a/solr/CHANGES.txt b/solr/CHANGES.txt index d5edef396f1..94960bb1d33 100644 --- a/solr/CHANGES.txt +++ b/solr/CHANGES.txt @@ -44,11 +44,21 @@ Upgrade Notes MemoryDocValues). If you used postingsFormat="Memory" or docValuesFormat="Memory" switch to "Direct" instead. (Dawid Weiss) +* SOLR-12586: The date format patterns used by ParseDateFieldUpdateProcessorFactory (present in "schemaless mode") + are now interpreted by Java 8's java.time.DateTimeFormatter instead of Joda Time. The pattern language is very + similar but not the same. Typically, simply update the pattern by changing an uppercase 'Z' to lowercase 'z' and + that's it. For the current recommended set of patterns in schemaless mode, see "Schemaless Mode" in the ref guide. + (David Smiley, Bar Rotstein) + Other Changes ---------------------- * SOLR-12614: Make "Nodes" view the default in AdminUI "Cloud" tab (janhoy) +* SOLR-12586: Remove Joda Time dependency. Upgrade ParseDateFieldUpdateProcessorFactory (present in "schemaless mode") + to use Java 8's java.time.DateTimeFormatter instead (see upgrade notes). + (David Smiley, Bar Rotstein) + ================== 7.5.0 ================== Consult the LUCENE_CHANGES.txt file for additional, low level, changes in this release. diff --git a/solr/contrib/prometheus-exporter/src/test-files/configsets/collection1/conf/solrconfig.xml b/solr/contrib/prometheus-exporter/src/test-files/configsets/collection1/conf/solrconfig.xml index 72c54304f24..37c41d8909c 100644 --- a/solr/contrib/prometheus-exporter/src/test-files/configsets/collection1/conf/solrconfig.xml +++ b/solr/contrib/prometheus-exporter/src/test-files/configsets/collection1/conf/solrconfig.xml @@ -164,22 +164,10 @@ - yyyy-MM-dd'T'HH:mm:ss.SSSZ - yyyy-MM-dd'T'HH:mm:ss,SSSZ - yyyy-MM-dd'T'HH:mm:ss.SSS - yyyy-MM-dd'T'HH:mm:ss,SSS - yyyy-MM-dd'T'HH:mm:ssZ - yyyy-MM-dd'T'HH:mm:ss - yyyy-MM-dd'T'HH:mmZ - yyyy-MM-dd'T'HH:mm - yyyy-MM-dd HH:mm:ss.SSSZ - yyyy-MM-dd HH:mm:ss,SSSZ - yyyy-MM-dd HH:mm:ss.SSS - yyyy-MM-dd HH:mm:ss,SSS - yyyy-MM-dd HH:mm:ssZ - yyyy-MM-dd HH:mm:ss - yyyy-MM-dd HH:mmZ - yyyy-MM-dd HH:mm + yyyy-MM-dd'T'HH:mm[:ss[.SSS]][z + yyyy-MM-dd'T'HH:mm[:ss[,SSS]][z + yyyy-MM-dd HH:mm[:ss[.SSS]][z + yyyy-MM-dd HH:mm[:ss[,SSS]][z yyyy-MM-dd diff --git a/solr/core/ivy.xml b/solr/core/ivy.xml index ee6fe80db73..5a0fd091301 100644 --- a/solr/core/ivy.xml +++ b/solr/core/ivy.xml @@ -44,7 +44,6 @@ - diff --git a/solr/core/src/java/org/apache/solr/core/ConfigSetService.java b/solr/core/src/java/org/apache/solr/core/ConfigSetService.java index 69e160b5da1..7ce1a52dc6b 100644 --- a/solr/core/src/java/org/apache/solr/core/ConfigSetService.java +++ b/solr/core/src/java/org/apache/solr/core/ConfigSetService.java @@ -21,6 +21,7 @@ import java.lang.invoke.MethodHandles; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; +import java.time.Instant; import java.util.Locale; import java.util.concurrent.ExecutionException; @@ -33,8 +34,6 @@ import org.apache.solr.common.SolrException; import org.apache.solr.common.util.NamedList; import org.apache.solr.schema.IndexSchema; import org.apache.solr.schema.IndexSchemaFactory; -import org.joda.time.format.DateTimeFormat; -import org.joda.time.format.DateTimeFormatter; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -212,12 +211,10 @@ public abstract class ConfigSetService { super(loader, configSetBase); } - public static final DateTimeFormatter cacheKeyFormatter = DateTimeFormat.forPattern("yyyyMMddHHmmss"); - public static String cacheName(Path schemaFile) throws IOException { long lastModified = Files.getLastModifiedTime(schemaFile).toMillis(); return String.format(Locale.ROOT, "%s:%s", - schemaFile.toString(), cacheKeyFormatter.print(lastModified)); + schemaFile.toString(), Instant.ofEpochMilli(lastModified).toString()); } @Override diff --git a/solr/core/src/java/org/apache/solr/update/processor/ParseDateFieldUpdateProcessorFactory.java b/solr/core/src/java/org/apache/solr/update/processor/ParseDateFieldUpdateProcessorFactory.java index 234b48bc15e..f0ea5d25720 100644 --- a/solr/core/src/java/org/apache/solr/update/processor/ParseDateFieldUpdateProcessorFactory.java +++ b/solr/core/src/java/org/apache/solr/update/processor/ParseDateFieldUpdateProcessorFactory.java @@ -17,6 +17,17 @@ package org.apache.solr.update.processor; import java.lang.invoke.MethodHandles; +import java.time.Instant; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.LocalTime; +import java.time.ZoneId; +import java.time.ZoneOffset; +import java.time.format.DateTimeFormatter; +import java.time.format.DateTimeFormatterBuilder; +import java.time.format.DateTimeParseException; +import java.time.temporal.TemporalAccessor; +import java.time.temporal.TemporalQueries; import java.util.Collection; import java.util.Date; import java.util.LinkedHashMap; @@ -24,6 +35,7 @@ import java.util.Locale; import java.util.Map; import org.apache.commons.lang.LocaleUtils; +import org.apache.solr.common.SolrException; import org.apache.solr.common.util.NamedList; import org.apache.solr.core.SolrCore; import org.apache.solr.request.SolrQueryRequest; @@ -31,10 +43,6 @@ import org.apache.solr.response.SolrQueryResponse; import org.apache.solr.schema.DateValueFieldType; import org.apache.solr.schema.FieldType; import org.apache.solr.schema.IndexSchema; -import org.joda.time.DateTime; -import org.joda.time.DateTimeZone; -import org.joda.time.format.DateTimeFormat; -import org.joda.time.format.DateTimeFormatter; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -57,8 +65,8 @@ import org.slf4j.LoggerFactory; *

*

* One or more date "format" specifiers must be specified. See - * Joda-time's DateTimeFormat javadocs for a description of format strings. + * Java 8's DateTimeFormatter javadocs for a description of format strings. *

*

* A default time zone name or offset may optionally be specified for those dates @@ -115,9 +123,8 @@ public class ParseDateFieldUpdateProcessorFactory extends FieldMutatingUpdatePro for (Map.Entry format : formats.entrySet()) { DateTimeFormatter parser = format.getValue(); try { - DateTime dateTime = parser.parseDateTime(srcStringVal); - return dateTime.withZone(DateTimeZone.UTC).toDate(); - } catch (IllegalArgumentException e) { + return Date.from(parseInstant(parser, srcStringVal)); + } catch (DateTimeParseException e) { log.debug("value '{}' is not parseable with format '{}'", new Object[] { srcStringVal, format.getKey() }); } @@ -144,15 +151,18 @@ public class ParseDateFieldUpdateProcessorFactory extends FieldMutatingUpdatePro } Object defaultTimeZoneParam = args.remove(DEFAULT_TIME_ZONE_PARAM); - DateTimeZone defaultTimeZone = DateTimeZone.UTC; + ZoneId defaultTimeZone = ZoneOffset.UTC; if (null != defaultTimeZoneParam) { - defaultTimeZone = DateTimeZone.forID(defaultTimeZoneParam.toString()); + defaultTimeZone = ZoneId.of(defaultTimeZoneParam.toString()); } Collection formatsParam = args.removeConfigArgs(FORMATS_PARAM); if (null != formatsParam) { for (String value : formatsParam) { - formats.put(value, DateTimeFormat.forPattern(value).withZone(defaultTimeZone).withLocale(locale)); + DateTimeFormatter formatter = new DateTimeFormatterBuilder().parseCaseInsensitive() + .appendPattern(value).toFormatter(locale).withZone(defaultTimeZone); + validateFormatter(formatter); + formats.put(value, formatter); } } super.init(args); @@ -172,4 +182,52 @@ public class ParseDateFieldUpdateProcessorFactory extends FieldMutatingUpdatePro return (null == type) || type instanceof DateValueFieldType; }; } + + public static void validateFormatter(DateTimeFormatter formatter) { + // check it's valid via round-trip + try { + parseInstant(formatter, formatter.format(Instant.now())); + } catch (Exception e) { + throw new SolrException(SolrException.ErrorCode.SERVER_ERROR, + "Bad or unsupported pattern: " + formatter.toFormat().toString(), e); + } + } + + // see https://bugs.java.com/bugdatabase/view_bug.do?bug_id=8177021 which is fixed in Java 9. + // The upshot is that trying to use parse(Instant::from) is unreliable in the event that + // the input string contains a timezone/offset that differs from the "override zone" + // (which we configure in DEFAULT_TIME_ZONE). Besides, we need the code below which handles + // the optionality of time. Were it not for that, we truly could do formatter.parse(Instant::from). + private static Instant parseInstant(DateTimeFormatter formatter, String dateStr) { + final TemporalAccessor temporal = formatter.parse(dateStr); + // Get Date; mandatory + LocalDate date = temporal.query(TemporalQueries.localDate());//mandatory + if (date == null) { + throw new SolrException(SolrException.ErrorCode.SERVER_ERROR, + "Date (year, month, day) is mandatory: " + formatter.toFormat().toString()); + } + // Get Time; optional + LocalTime time = temporal.query(TemporalQueries.localTime()); + if (time == null) { + time = LocalTime.MIN; + } + + final LocalDateTime localDateTime = LocalDateTime.of(date, time); + + // Get Zone Offset; optional + ZoneOffset offset = temporal.query(TemporalQueries.offset()); + if (offset == null) { + // no Zone offset; get Zone ID + ZoneId zoneId = temporal.query(TemporalQueries.zone()); + if (zoneId == null) { + zoneId = formatter.getZone(); + if (zoneId == null) { + zoneId = ZoneOffset.UTC; + } + } + return localDateTime.atZone(zoneId).toInstant(); + } else { + return localDateTime.toInstant(offset); + } + } } diff --git a/solr/core/src/test-files/solr/collection1/conf/solrconfig-add-schema-fields-update-processor-chains.xml b/solr/core/src/test-files/solr/collection1/conf/solrconfig-add-schema-fields-update-processor-chains.xml index b0b63dfbb6e..4394d5c7a6e 100644 --- a/solr/core/src/test-files/solr/collection1/conf/solrconfig-add-schema-fields-update-processor-chains.xml +++ b/solr/core/src/test-files/solr/collection1/conf/solrconfig-add-schema-fields-update-processor-chains.xml @@ -179,22 +179,10 @@ - yyyy-MM-dd'T'HH:mm:ss.SSSZ - yyyy-MM-dd'T'HH:mm:ss,SSSZ - yyyy-MM-dd'T'HH:mm:ss.SSS - yyyy-MM-dd'T'HH:mm:ss,SSS - yyyy-MM-dd'T'HH:mm:ssZ - yyyy-MM-dd'T'HH:mm:ss - yyyy-MM-dd'T'HH:mmZ - yyyy-MM-dd'T'HH:mm - yyyy-MM-dd HH:mm:ss.SSSZ - yyyy-MM-dd HH:mm:ss,SSSZ - yyyy-MM-dd HH:mm:ss.SSS - yyyy-MM-dd HH:mm:ss,SSS - yyyy-MM-dd HH:mm:ssZ - yyyy-MM-dd HH:mm:ss - yyyy-MM-dd HH:mmZ - yyyy-MM-dd HH:mm + yyyy-MM-dd'T'HH:mm[:ss[.SSS]][z + yyyy-MM-dd'T'HH:mm[:ss[,SSS]][z + yyyy-MM-dd HH:mm[:ss[.SSS]][z + yyyy-MM-dd HH:mm[:ss[,SSS]][z yyyy-MM-dd diff --git a/solr/core/src/test-files/solr/collection1/conf/solrconfig-parsing-update-processor-chains.xml b/solr/core/src/test-files/solr/collection1/conf/solrconfig-parsing-update-processor-chains.xml index 5930d37d775..83be4eef789 100644 --- a/solr/core/src/test-files/solr/collection1/conf/solrconfig-parsing-update-processor-chains.xml +++ b/solr/core/src/test-files/solr/collection1/conf/solrconfig-parsing-update-processor-chains.xml @@ -29,35 +29,35 @@ - yyyy-MM-dd'T'HH:mm:ss.SSSZ + yyyy-MM-dd'T'HH:mm:ss.SSSz - yyyy-MM-dd'T'HH:mm:ss.SSSZ + yyyy-MM-dd'T'HH:mm:ss.SSSz false - yyyy-MM-dd'T'HH:mm:ss.SSSZ + yyyy-MM-dd'T'HH:mm:ss.SSSz solr.DatePointField - yyyy-MM-dd'T'HH:mm:ss.SSSZ + yyyy-MM-dd'T'HH:mm:ss.SSSz solr.TrieDateField - yyyy-MM-dd'T'HH:mm:ss.SSSZ + yyyy-MM-dd'T'HH:mm:ss.SSSz @@ -65,8 +65,7 @@ America/New_York en_US - yyyy-MM-dd'T'HH:mm:ss.SSSZ - yyyy-MM-dd'T'HH:mm:ss.SSS + yyyy-MM-dd'T'HH:mm:ss.SSS[z] @@ -75,7 +74,7 @@ America/Los_Angeles - MM/dd/yyyy + M/d/yyyy @@ -85,30 +84,16 @@ UTC en_US - yyyy-MM-dd'T'HH:mm:ss.SSSZ - yyyy-MM-dd'T'HH:mm:ss,SSSZ - yyyy-MM-dd'T'HH:mm:ss.SSS - yyyy-MM-dd'T'HH:mm:ss,SSS - yyyy-MM-dd'T'HH:mm:ssZ - yyyy-MM-dd'T'HH:mm:ss - yyyy-MM-dd'T'HH:mmZ - yyyy-MM-dd'T'HH:mm - yyyy-MM-dd HH:mm:ss.SSSZ - yyyy-MM-dd HH:mm:ss,SSSZ - yyyy-MM-dd HH:mm:ss.SSS - yyyy-MM-dd HH:mm:ss,SSS - yyyy-MM-dd HH:mm:ssZ - yyyy-MM-dd HH:mm:ss - yyyy-MM-dd HH:mmZ - yyyy-MM-dd HH:mm - yyyy-MM-dd hh:mm a - yyyy-MM-dd hh:mma + yyyy-MM-dd'T'HH:mm[:ss[.SSS]][z + yyyy-MM-dd'T'HH:mm[:ss[,SSS]][z + yyyy-MM-dd HH:mm[:ss[.SSS]][z + yyyy-MM-dd HH:mm[:ss[,SSS]][z yyyy-MM-dd - EEE MMM dd HH:mm:ss Z yyyy - EEE MMM dd HH:mm:ss yyyy Z - EEE MMM dd HH:mm:ss yyyy - EEE, dd MMM yyyy HH:mm:ss Z - EEEE, dd-MMM-yy HH:mm:ss Z + yyyy-MM-dd hh:mm[ ]a + EEE MMM dd HH:mm:ss ZZZ yyyy + EEE MMM dd HH:mm:ss yyyy[ z] + EEE, dd MMM yyyy HH:mm:ss z + EEEE, dd-MMM-yy HH:mm:ss z EEEE, MMMM dd, yyyy MMMM dd, yyyy MMM. dd, yyyy @@ -229,7 +214,7 @@ yyyy-MM-dd - yyyy-MM-dd'T'HH:mm:ss.SSSZ + yyyy-MM-dd'T'HH:mm:ss.SSSz yyyy-MM-dd'T'HH:mm diff --git a/solr/core/src/test-files/solr/collection1/conf/solrconfig-schemaless.xml b/solr/core/src/test-files/solr/collection1/conf/solrconfig-schemaless.xml index 4f10a8e0e62..446f3f0feb2 100644 --- a/solr/core/src/test-files/solr/collection1/conf/solrconfig-schemaless.xml +++ b/solr/core/src/test-files/solr/collection1/conf/solrconfig-schemaless.xml @@ -61,22 +61,10 @@ - yyyy-MM-dd'T'HH:mm:ss.SSSZ - yyyy-MM-dd'T'HH:mm:ss,SSSZ - yyyy-MM-dd'T'HH:mm:ss.SSS - yyyy-MM-dd'T'HH:mm:ss,SSS - yyyy-MM-dd'T'HH:mm:ssZ - yyyy-MM-dd'T'HH:mm:ss - yyyy-MM-dd'T'HH:mmZ - yyyy-MM-dd'T'HH:mm - yyyy-MM-dd HH:mm:ss.SSSZ - yyyy-MM-dd HH:mm:ss,SSSZ - yyyy-MM-dd HH:mm:ss.SSS - yyyy-MM-dd HH:mm:ss,SSS - yyyy-MM-dd HH:mm:ssZ - yyyy-MM-dd HH:mm:ss - yyyy-MM-dd HH:mmZ - yyyy-MM-dd HH:mm + yyyy-MM-dd'T'HH:mm[:ss[.SSS]][z + yyyy-MM-dd'T'HH:mm[:ss[,SSS]][z + yyyy-MM-dd HH:mm[:ss[.SSS]][z + yyyy-MM-dd HH:mm[:ss[,SSS]][z yyyy-MM-dd diff --git a/solr/core/src/test-files/solr/configsets/_default/conf/solrconfig.xml b/solr/core/src/test-files/solr/configsets/_default/conf/solrconfig.xml index 51f2c639c64..d393316f207 100644 --- a/solr/core/src/test-files/solr/configsets/_default/conf/solrconfig.xml +++ b/solr/core/src/test-files/solr/configsets/_default/conf/solrconfig.xml @@ -1141,22 +1141,10 @@ - yyyy-MM-dd'T'HH:mm:ss.SSSZ - yyyy-MM-dd'T'HH:mm:ss,SSSZ - yyyy-MM-dd'T'HH:mm:ss.SSS - yyyy-MM-dd'T'HH:mm:ss,SSS - yyyy-MM-dd'T'HH:mm:ssZ - yyyy-MM-dd'T'HH:mm:ss - yyyy-MM-dd'T'HH:mmZ - yyyy-MM-dd'T'HH:mm - yyyy-MM-dd HH:mm:ss.SSSZ - yyyy-MM-dd HH:mm:ss,SSSZ - yyyy-MM-dd HH:mm:ss.SSS - yyyy-MM-dd HH:mm:ss,SSS - yyyy-MM-dd HH:mm:ssZ - yyyy-MM-dd HH:mm:ss - yyyy-MM-dd HH:mmZ - yyyy-MM-dd HH:mm + yyyy-MM-dd'T'HH:mm[:ss[.SSS]][z + yyyy-MM-dd'T'HH:mm[:ss[,SSS]][z + yyyy-MM-dd HH:mm[:ss[.SSS]][z + yyyy-MM-dd HH:mm[:ss[,SSS]][z yyyy-MM-dd diff --git a/solr/core/src/test/org/apache/solr/update/processor/AddSchemaFieldsUpdateProcessorFactoryTest.java b/solr/core/src/test/org/apache/solr/update/processor/AddSchemaFieldsUpdateProcessorFactoryTest.java index d1a3a535a48..96cc6766e93 100644 --- a/solr/core/src/test/org/apache/solr/update/processor/AddSchemaFieldsUpdateProcessorFactoryTest.java +++ b/solr/core/src/test/org/apache/solr/update/processor/AddSchemaFieldsUpdateProcessorFactoryTest.java @@ -17,17 +17,18 @@ package org.apache.solr.update.processor; import java.io.File; +import java.time.Instant; +import java.time.LocalDateTime; +import java.time.ZoneOffset; +import java.time.format.DateTimeFormatter; import java.util.Collections; import java.util.Date; +import java.util.Locale; import org.apache.commons.io.FileUtils; import org.apache.solr.common.SolrInputDocument; import org.apache.solr.common.params.ModifiableSolrParams; import org.apache.solr.schema.IndexSchema; -import org.joda.time.DateTime; -import org.joda.time.format.DateTimeFormat; -import org.joda.time.format.DateTimeFormatter; -import org.joda.time.format.ISODateTimeFormat; import org.junit.After; import org.junit.Before; @@ -62,9 +63,7 @@ public class AddSchemaFieldsUpdateProcessorFactoryTest extends UpdateProcessorTe IndexSchema schema = h.getCore().getLatestSchema(); final String fieldName = "newfield1"; assertNull(schema.getFieldOrNull(fieldName)); - String dateString = "2010-11-12T13:14:15.168Z"; - DateTimeFormatter dateTimeFormatter = ISODateTimeFormat.dateTime(); - Date date = dateTimeFormatter.parseDateTime(dateString).toDate(); + Date date = Date.from(Instant.now()); SolrInputDocument d = processAdd("add-fields-no-run-processor", doc(f("id", "1"), f(fieldName, date))); assertNotNull(d); schema = h.getCore().getLatestSchema(); @@ -202,11 +201,11 @@ public class AddSchemaFieldsUpdateProcessorFactoryTest extends UpdateProcessorTe String field3String2 = "-5.28E-3"; Double field3Value2 = -5.28E-3; String field4String1 = "1999-04-17 17:42"; - DateTimeFormatter dateTimeFormatter = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm").withZoneUTC(); - DateTime dateTime = dateTimeFormatter.parseDateTime(field4String1); - Date field4Value1 = dateTime.toDate(); - DateTimeFormatter dateTimeFormatter2 = DateTimeFormat.forPattern("yyyy-MM-dd'T'HH:mm:ss").withZoneUTC(); - String field4Value1String = dateTimeFormatter2.print(dateTime) + "Z"; + DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm", Locale.ROOT).withZone(ZoneOffset.UTC); + LocalDateTime dateTime = LocalDateTime.parse(field4String1, dateTimeFormatter); + Date field4Value1 = Date.from(dateTime.atZone(ZoneOffset.UTC).toInstant()); + DateTimeFormatter dateTimeFormatter2 = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss", Locale.ROOT).withZone(ZoneOffset.UTC); + String field4Value1String = dateTime.format(dateTimeFormatter2) + "Z"; SolrInputDocument d = processAdd ("parse-and-add-fields", doc(f("id", "6"), f(fieldName1, field1String1, field1String2, field1String3), diff --git a/solr/core/src/test/org/apache/solr/update/processor/ParsingFieldUpdateProcessorsTest.java b/solr/core/src/test/org/apache/solr/update/processor/ParsingFieldUpdateProcessorsTest.java index 3aeb1fbfccf..e26ca4122bf 100644 --- a/solr/core/src/test/org/apache/solr/update/processor/ParsingFieldUpdateProcessorsTest.java +++ b/solr/core/src/test/org/apache/solr/update/processor/ParsingFieldUpdateProcessorsTest.java @@ -16,28 +16,35 @@ */ package org.apache.solr.update.processor; -import org.apache.solr.common.SolrInputDocument; -import org.apache.solr.schema.IndexSchema; -import org.joda.time.DateTime; -import org.joda.time.DateTimeZone; -import org.joda.time.format.DateTimeFormat; -import org.joda.time.format.DateTimeFormatter; -import org.joda.time.format.ISODateTimeFormat; -import org.junit.BeforeClass; - +import java.time.Instant; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.OffsetDateTime; +import java.time.ZoneId; +import java.time.ZoneOffset; +import java.time.ZonedDateTime; +import java.time.format.DateTimeFormatter; +import java.time.temporal.TemporalAccessor; import java.util.Date; import java.util.HashMap; import java.util.HashSet; import java.util.LinkedHashMap; +import java.util.Locale; import java.util.Map; import java.util.Set; +import org.apache.solr.common.SolrInputDocument; +import org.apache.solr.schema.IndexSchema; +import org.junit.BeforeClass; + /** * Tests for the field mutating update processors * that parse Dates, Longs, Doubles, and Booleans. */ public class ParsingFieldUpdateProcessorsTest extends UpdateProcessorTestBase { private static final double EPSILON = 1E-15; + private static final DateTimeFormatter isoDateOptionalTimeFormatter = + DateTimeFormatter.ofPattern("yyyy-MM-dd['T'HH:mm[:ss[.SSS]]][z", Locale.ROOT).withZone(ZoneOffset.UTC); @BeforeClass public static void beforeClass() throws Exception { @@ -50,10 +57,8 @@ public class ParsingFieldUpdateProcessorsTest extends UpdateProcessorTestBase { String dateString = "2010-11-12T13:14:15.168Z"; SolrInputDocument d = processAdd("parse-date", doc(f("id", "9"), f("date_dt", dateString))); assertNotNull(d); - DateTimeFormatter dateTimeFormatter = ISODateTimeFormat.dateTime(); - DateTime dateTime = dateTimeFormatter.parseDateTime(dateString); assertTrue(d.getFieldValue("date_dt") instanceof Date); - assertEquals(dateTime.getMillis(), ((Date) d.getFieldValue("date_dt")).getTime()); + assertEquals(Instant.parse(dateString), ((Date) d.getFieldValue("date_dt")).toInstant()); assertU(commit()); assertQ(req("id:9"), "//date[@name='date_dt'][.='" + dateString + "']"); } @@ -64,10 +69,8 @@ public class ParsingFieldUpdateProcessorsTest extends UpdateProcessorTestBase { String dateString = "2010-11-12T13:14:15.168Z"; SolrInputDocument d = processAdd("parse-date", doc(f("id", "39"), f("date_tdt", dateString))); assertNotNull(d); - DateTimeFormatter dateTimeFormatter = ISODateTimeFormat.dateTime(); - DateTime dateTime = dateTimeFormatter.parseDateTime(dateString); assertTrue(d.getFieldValue("date_tdt") instanceof Date); - assertEquals(dateTime.getMillis(), ((Date) d.getFieldValue("date_tdt")).getTime()); + assertEquals(Instant.parse(dateString), ((Date) d.getFieldValue("date_tdt")).toInstant()); assertU(commit()); assertQ(req("id:39"), "//date[@name='date_tdt'][.='" + dateString + "']"); } @@ -77,14 +80,12 @@ public class ParsingFieldUpdateProcessorsTest extends UpdateProcessorTestBase { IndexSchema schema = h.getCore().getLatestSchema(); assertNull(schema.getFieldOrNull("not_in_schema")); String dateString = "2010-11-12T13:14:15.168Z"; - DateTimeFormatter dateTimeFormatter = ISODateTimeFormat.dateTime(); - DateTime dateTime = dateTimeFormatter.parseDateTime(dateString); SolrInputDocument d = processAdd("parse-date-no-run-processor", doc(f("id", "18"), f("not_in_schema", dateString))); assertNotNull(d); assertTrue(d.getFieldValue("not_in_schema") instanceof Date); - assertEquals(dateTime.getMillis(), ((Date)d.getFieldValue("not_in_schema")).getTime()); + assertEquals(Instant.parse(dateString), ((Date)d.getFieldValue("not_in_schema")).toInstant()); d = processAdd("parse-date-no-run-processor", doc(f("id", "36"), f("not_in_schema", "not a date", dateString))); @@ -116,12 +117,8 @@ public class ParsingFieldUpdateProcessorsTest extends UpdateProcessorTestBase { ("parse-date-non-UTC-defaultTimeZone", doc(f("id", "99"), f("dateUTC_dt", dateStringUTC), f("dateNoTimeZone_dt", dateStringNoTimeZone))); assertNotNull(d); - String pattern = "yyyy-MM-dd'T'HH:mm:ss.SSSZ"; - DateTimeFormatter dateTimeFormatterUTC = DateTimeFormat.forPattern(pattern); - DateTime dateTimeUTC = dateTimeFormatterUTC.parseDateTime(dateStringUTC); assertTrue(d.getFieldValue("dateUTC_dt") instanceof Date); assertTrue(d.getFieldValue("dateNoTimeZone_dt") instanceof Date); - assertEquals(dateTimeUTC.getMillis(), ((Date) d.getFieldValue("dateUTC_dt")).getTime()); assertU(commit()); assertQ(req("id:99") ,"//date[@name='dateUTC_dt'][.='" + dateStringUTC + "']" @@ -132,22 +129,18 @@ public class ParsingFieldUpdateProcessorsTest extends UpdateProcessorTestBase { IndexSchema schema = h.getCore().getLatestSchema(); assertNull(schema.getFieldOrNull("not_in_schema")); String dateString = "2010-11-12T13:14:15.168Z"; - DateTimeFormatter dateTimeFormatter = ISODateTimeFormat.dateTime(); - DateTime dateTime = dateTimeFormatter.parseDateTime(dateString); SolrInputDocument d = processAdd("parse-date-explicit-not-in-schema-selector-no-run-processor", doc(f("id", "88"), f("not_in_schema", dateString))); assertNotNull(d); assertTrue(d.getFieldValue("not_in_schema") instanceof Date); - assertEquals(dateTime.getMillis(), ((Date)d.getFieldValue("not_in_schema")).getTime()); + assertEquals(Instant.parse(dateString), ((Date)d.getFieldValue("not_in_schema")).toInstant()); } public void testParseDateExplicitTypeClassSelector() throws Exception { IndexSchema schema = h.getCore().getLatestSchema(); assertNotNull(schema.getFieldOrNull("date_dt")); String dateString = "2010-11-12T13:14:15.168Z"; - DateTimeFormatter dateTimeFormatter = ISODateTimeFormat.dateTime(); - DateTime dateTime = dateTimeFormatter.parseDateTime(dateString); SolrInputDocument d; if (schema.getField("date_dt").getType().isPointField()) { d = processAdd("parse-date-explicit-typeclass-point-selector-no-run-processor", @@ -159,71 +152,66 @@ public class ParsingFieldUpdateProcessorsTest extends UpdateProcessorTestBase { assertNotNull(d); assertTrue(d.getFieldValue("date_dt") instanceof Date); - assertEquals(dateTime.getMillis(), ((Date)d.getFieldValue("date_dt")).getTime()); + assertEquals(Instant.parse(dateString), ((Date)d.getFieldValue("date_dt")).toInstant()); } public void testParseUSPacificDate() throws Exception { IndexSchema schema = h.getCore().getLatestSchema(); assertNull(schema.getFieldOrNull("not_in_schema")); String dateString = "8/9/2010"; // Interpreted as 00:00 US Pacific Daylight Time = UTC+07:00 - String dateStringUTC = "2010-08-09T07:00:00.000Z"; SolrInputDocument d = processAdd("US-Pacific-parse-date-no-run-processor", doc(f("id", "288"), f("not_in_schema", dateString))); assertNotNull(d); assertTrue(d.getFieldValue("not_in_schema") instanceof Date); - assertEquals(dateStringUTC, - (new DateTime(((Date)d.getFieldValue("not_in_schema")).getTime(),DateTimeZone.UTC)).toString()); + assertEquals(Instant.parse("2010-08-09T07:00:00.000Z"), ((Date)d.getFieldValue("not_in_schema")).toInstant()); } public void testParseDateFormats() throws Exception { String[] formatExamples = { - "yyyy-MM-dd'T'HH:mm:ss.SSSZ", "2010-01-15T00:00:00.000Z", - "yyyy-MM-dd'T'HH:mm:ss,SSSZ", "2010-01-15T00:00:00,000Z", - "yyyy-MM-dd'T'HH:mm:ss.SSS", "2010-01-15T00:00:00.000", - "yyyy-MM-dd'T'HH:mm:ss,SSS", "2010-01-15T00:00:00,000", - "yyyy-MM-dd'T'HH:mm:ssZ", "2010-01-15T00:00:00Z", - "yyyy-MM-dd'T'HH:mm:ss", "2010-01-15T00:00:00", - "yyyy-MM-dd'T'HH:mmZ", "2010-01-15T00:00Z", - "yyyy-MM-dd'T'HH:mm", "2010-01-15T00:00", - "yyyy-MM-dd HH:mm:ss.SSSZ", "2010-01-15 00:00:00.000Z", - "yyyy-MM-dd HH:mm:ss,SSSZ", "2010-01-15 00:00:00,000Z", - "yyyy-MM-dd HH:mm:ss.SSS", "2010-01-15 00:00:00.000", - "yyyy-MM-dd HH:mm:ss,SSS", "2010-01-15 00:00:00,000", - "yyyy-MM-dd HH:mm:ssZ", "2010-01-15 00:00:00Z", - "yyyy-MM-dd HH:mm:ss", "2010-01-15 00:00:00", - "yyyy-MM-dd HH:mmZ", "2010-01-15 00:00Z", - "yyyy-MM-dd HH:mm", "2010-01-15 00:00", - "yyyy-MM-dd hh:mm a", "2010-01-15 12:00 AM", - "yyyy-MM-dd hh:mma", "2010-01-15 12:00AM", - "yyyy-MM-dd", "2010-01-15", - "EEE MMM dd HH:mm:ss Z yyyy", "Fri Jan 15 00:00:00 +0000 2010", - "EEE MMM dd HH:mm:ss yyyy Z", "Fri Jan 15 00:00:00 2010 +00:00", - "EEE MMM dd HH:mm:ss yyyy", "Fri Jan 15 00:00:00 2010", - "EEE, dd MMM yyyy HH:mm:ss Z", "Fri, 15 Jan 2010 00:00:00 +00:00", - "EEEE, dd-MMM-yy HH:mm:ss Z", "Friday, 15-Jan-10 00:00:00 +00:00", - "EEEE, MMMM dd, yyyy", "Friday, January 15, 2010", - "MMMM dd, yyyy", "January 15, 2010", - "MMM. dd, yyyy", "Jan. 15, 2010" + "2010-01-15T00:00:00.000Z", + "2010-01-15T00:00:00,000Z", + "2010-01-15T00:00:00.000", + "2010-01-15T00:00:00,000", + "2010-01-15T00:00:00Z", + "2010-01-15T00:00:00", + "2010-01-15T00:00Z", + "2010-01-15T00:00", + "2010-01-15 00:00:00.000Z", + "2010-01-15 00:00:00,000Z", + "2010-01-15 00:00:00.000", + "2010-01-15 00:00:00,000", + "2010-01-15 00:00:00Z", + "2010-01-15 00:00:00", + "2010-01-15 00:00Z", + "2010-01-15 00:00", + "2010-01-15 12:00 AM", + "2010-01-15 12:00AM", + "2010-01-15", + "Fri Jan 15 00:00:00 +0000 2010", + "Fri Jan 15 00:00:00 2010 +00:00", + "Fri Jan 15 00:00:00 2010", + "Fri, 15 Jan 2010 00:00:00 +00:00", + "Friday, 15-Jan-10 00:00:00 +00:00", + "Friday, January 15, 2010", + "January 15, 2010", + "Jan. 15, 2010" }; IndexSchema schema = h.getCore().getLatestSchema(); assertNotNull(schema.getFieldOrNull("dateUTC_dt")); // should match "*_dt" dynamic field - String dateTimePattern = "yyyy-MM-dd'T'HH:mm:ss.SSSZ"; - DateTimeFormatter dateTimeFormatterUTC = DateTimeFormat.forPattern(dateTimePattern); - DateTime dateTimeUTC = dateTimeFormatterUTC.parseDateTime(formatExamples[1]); + Instant expectedInstant = Instant.parse(formatExamples[0]); - for (int i = 0 ; i < formatExamples.length ; i += 2) { - String format = formatExamples[i]; - String dateString = formatExamples[i + 1]; + for (int i = 0 ; i < formatExamples.length ; ++i) { + String dateString = formatExamples[i]; String id = "95" + i; SolrInputDocument d = processAdd("parse-date-UTC-defaultTimeZone-no-run-processor", doc(f("id", id), f("dateUTC_dt", dateString))); assertNotNull(d); - assertTrue("date '" + dateString + "' with format '" + format + "' is not mutated to a Date", + assertTrue("index: " + i + " date '" + dateString + "' is not mutated to a Date", d.getFieldValue("dateUTC_dt") instanceof Date); - assertEquals("date '" + dateString + "' with format '" + format + "' mismatched milliseconds", - dateTimeUTC.getMillis(), ((Date)d.getFieldValue("dateUTC_dt")).getTime()); + assertEquals("date '" + dateString + "' mismatched milliseconds", + expectedInstant, ((Date)d.getFieldValue("dateUTC_dt")).toInstant()); } } @@ -232,23 +220,20 @@ public class ParsingFieldUpdateProcessorsTest extends UpdateProcessorTestBase { assertNull(schema.getFieldOrNull("not_in_schema")); String frenchDateString = "le vendredi 15 janvier 2010"; String dateString = "2010-01-15T00:00:00.000Z"; - DateTimeFormatter dateTimeFormatter = ISODateTimeFormat.dateTime(); - DateTime dateTime = dateTimeFormatter.parseDateTime(dateString); SolrInputDocument d = processAdd("parse-french-date-UTC-defaultTimeZone-no-run-processor", doc(f("id", "88"), f("not_in_schema", frenchDateString))); assertNotNull(d); assertTrue(d.getFieldValue("not_in_schema") instanceof Date); - assertEquals(dateTime.getMillis(), ((Date)d.getFieldValue("not_in_schema")).getTime()); + assertEquals(Instant.parse(dateString), ((Date)d.getFieldValue("not_in_schema")).toInstant()); } public void testFailedParseMixedDate() throws Exception { IndexSchema schema = h.getCore().getLatestSchema(); assertNull(schema.getFieldOrNull("not_in_schema")); - DateTimeFormatter dateTimeFormatter = ISODateTimeFormat.dateOptionalTimeParser().withZoneUTC(); Map mixed = new HashMap<>(); String[] dateStrings = { "2020-05-13T18:47", "1989-12-14", "1682-07-22T18:33:00.000Z" }; for (String dateString : dateStrings) { - mixed.put(dateTimeFormatter.parseDateTime(dateString).toDate(), dateString); + mixed.put(parse(isoDateOptionalTimeFormatter, dateString), dateString); } Double extraDouble = 29.554d; mixed.put(extraDouble, extraDouble); // Double-typed field value @@ -805,11 +790,10 @@ public class ParsingFieldUpdateProcessorsTest extends UpdateProcessorTestBase { longs.remove(o); } - DateTimeFormatter dateTimeFormatter = ISODateTimeFormat.dateOptionalTimeParser().withZoneUTC(); Map dates = new HashMap<>(); String[] dateStrings = { "2020-05-13T18:47", "1989-12-14", "1682-07-22T18:33:00.000Z" }; for (String dateString : dateStrings) { - dates.put(dateTimeFormatter.parseDateTime(dateString).toDate(), dateString); + dates.put(parse(isoDateOptionalTimeFormatter, dateString), dateString); } d = processAdd(chain, doc(f("id", "343"), f(fieldName, dates.values()))); assertNotNull(d); @@ -896,13 +880,12 @@ public class ParsingFieldUpdateProcessorsTest extends UpdateProcessorTestBase { } assertTrue(mixedBooleans.isEmpty()); - dateTimeFormatter = ISODateTimeFormat.dateOptionalTimeParser().withZoneUTC(); Map mixedDates = new HashMap<>(); dateStrings = new String[] { "2020-05-13T18:47", "1989-12-14", "1682-07-22T18:33:00.000Z" }; for (String dateString : dateStrings) { - mixedDates.put(dateTimeFormatter.parseDateTime(dateString).toDate(), dateString); + mixedDates.put(parse(isoDateOptionalTimeFormatter, dateString), dateString); } - Date extraDate = dateTimeFormatter.parseDateTime("2003-04-24").toDate(); + Date extraDate = parse(isoDateOptionalTimeFormatter, "2003-04-24"); mixedDates.put(extraDate, extraDate); // Date-typed field value d = processAdd(chain, doc(f("id", "3395"), f(fieldName, mixedDates.values()))); assertNotNull(d); @@ -912,4 +895,24 @@ public class ParsingFieldUpdateProcessorsTest extends UpdateProcessorTestBase { } assertTrue(mixedDates.isEmpty()); } + + private Date parse(DateTimeFormatter dateTimeFormatter, String dateString) { + final TemporalAccessor temporalAccessor = dateTimeFormatter.parseBest(dateString, OffsetDateTime::from, + ZonedDateTime::from, LocalDateTime::from, LocalDate::from, Instant::from); + return temporalToDate(temporalAccessor, dateTimeFormatter.getZone()); + } + + private Date temporalToDate(TemporalAccessor in, ZoneId timeZoneId) { + if (in instanceof OffsetDateTime) { + return Date.from(((OffsetDateTime) in).toInstant()); + } else if (in instanceof ZonedDateTime) { + return Date.from(((ZonedDateTime) in).toInstant()); + } else if (in instanceof LocalDateTime) { + return Date.from(((LocalDateTime) in).atZone(timeZoneId).toInstant()); + } else if (in instanceof Instant) { + return Date.from((Instant) in); + } else { + return Date.from(((LocalDate) in).atStartOfDay(timeZoneId).toInstant()); + } + } } diff --git a/solr/example/files/conf/solrconfig.xml b/solr/example/files/conf/solrconfig.xml index bca0df80286..7bc8d347296 100644 --- a/solr/example/files/conf/solrconfig.xml +++ b/solr/example/files/conf/solrconfig.xml @@ -1161,22 +1161,10 @@ - yyyy-MM-dd'T'HH:mm:ss.SSSZ - yyyy-MM-dd'T'HH:mm:ss,SSSZ - yyyy-MM-dd'T'HH:mm:ss.SSS - yyyy-MM-dd'T'HH:mm:ss,SSS - yyyy-MM-dd'T'HH:mm:ssZ - yyyy-MM-dd'T'HH:mm:ss - yyyy-MM-dd'T'HH:mmZ - yyyy-MM-dd'T'HH:mm - yyyy-MM-dd HH:mm:ss.SSSZ - yyyy-MM-dd HH:mm:ss,SSSZ - yyyy-MM-dd HH:mm:ss.SSS - yyyy-MM-dd HH:mm:ss,SSS - yyyy-MM-dd HH:mm:ssZ - yyyy-MM-dd HH:mm:ss - yyyy-MM-dd HH:mmZ - yyyy-MM-dd HH:mm + yyyy-MM-dd'T'HH:mm[:ss[.SSS]][z + yyyy-MM-dd'T'HH:mm[:ss[,SSS]][z + yyyy-MM-dd HH:mm[:ss[.SSS]][z + yyyy-MM-dd HH:mm[:ss[,SSS]][z yyyy-MM-dd diff --git a/solr/licenses/joda-time-2.2.jar.sha1 b/solr/licenses/joda-time-2.2.jar.sha1 deleted file mode 100644 index 5e68639267a..00000000000 --- a/solr/licenses/joda-time-2.2.jar.sha1 +++ /dev/null @@ -1 +0,0 @@ -a5f29a7acaddea3f4af307e8cf2d0cc82645fd7d diff --git a/solr/licenses/joda-time-LICENSE-ASL.txt b/solr/licenses/joda-time-LICENSE-ASL.txt deleted file mode 100644 index d6456956733..00000000000 --- a/solr/licenses/joda-time-LICENSE-ASL.txt +++ /dev/null @@ -1,202 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed 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. diff --git a/solr/licenses/joda-time-NOTICE.txt b/solr/licenses/joda-time-NOTICE.txt deleted file mode 100644 index dffbcf31cac..00000000000 --- a/solr/licenses/joda-time-NOTICE.txt +++ /dev/null @@ -1,5 +0,0 @@ -============================================================================= -= NOTICE file corresponding to section 4d of the Apache License Version 2.0 = -============================================================================= -This product includes software developed by -Joda.org (http://www.joda.org/). diff --git a/solr/server/solr/configsets/_default/conf/solrconfig.xml b/solr/server/solr/configsets/_default/conf/solrconfig.xml index 51f2c639c64..d393316f207 100644 --- a/solr/server/solr/configsets/_default/conf/solrconfig.xml +++ b/solr/server/solr/configsets/_default/conf/solrconfig.xml @@ -1141,22 +1141,10 @@ - yyyy-MM-dd'T'HH:mm:ss.SSSZ - yyyy-MM-dd'T'HH:mm:ss,SSSZ - yyyy-MM-dd'T'HH:mm:ss.SSS - yyyy-MM-dd'T'HH:mm:ss,SSS - yyyy-MM-dd'T'HH:mm:ssZ - yyyy-MM-dd'T'HH:mm:ss - yyyy-MM-dd'T'HH:mmZ - yyyy-MM-dd'T'HH:mm - yyyy-MM-dd HH:mm:ss.SSSZ - yyyy-MM-dd HH:mm:ss,SSSZ - yyyy-MM-dd HH:mm:ss.SSS - yyyy-MM-dd HH:mm:ss,SSS - yyyy-MM-dd HH:mm:ssZ - yyyy-MM-dd HH:mm:ss - yyyy-MM-dd HH:mmZ - yyyy-MM-dd HH:mm + yyyy-MM-dd'T'HH:mm[:ss[.SSS]][z + yyyy-MM-dd'T'HH:mm[:ss[,SSS]][z + yyyy-MM-dd HH:mm[:ss[.SSS]][z + yyyy-MM-dd HH:mm[:ss[,SSS]][z yyyy-MM-dd diff --git a/solr/solr-ref-guide/src/schemaless-mode.adoc b/solr/solr-ref-guide/src/schemaless-mode.adoc index b62a92ee0c3..0a2f555bc1b 100644 --- a/solr/solr-ref-guide/src/schemaless-mode.adoc +++ b/solr/solr-ref-guide/src/schemaless-mode.adoc @@ -103,22 +103,10 @@ To start, you should define it as follows (see the javadoc links below for updat - yyyy-MM-dd'T'HH:mm:ss.SSSZ - yyyy-MM-dd'T'HH:mm:ss,SSSZ - yyyy-MM-dd'T'HH:mm:ss.SSS - yyyy-MM-dd'T'HH:mm:ss,SSS - yyyy-MM-dd'T'HH:mm:ssZ - yyyy-MM-dd'T'HH:mm:ss - yyyy-MM-dd'T'HH:mmZ - yyyy-MM-dd'T'HH:mm - yyyy-MM-dd HH:mm:ss.SSSZ - yyyy-MM-dd HH:mm:ss,SSSZ - yyyy-MM-dd HH:mm:ss.SSS - yyyy-MM-dd HH:mm:ss,SSS - yyyy-MM-dd HH:mm:ssZ - yyyy-MM-dd HH:mm:ss - yyyy-MM-dd HH:mmZ - yyyy-MM-dd HH:mm + yyyy-MM-dd'T'HH:mm[:ss[.SSS]][z + yyyy-MM-dd'T'HH:mm[:ss[,SSS]][z + yyyy-MM-dd HH:mm[:ss[.SSS]][z + yyyy-MM-dd HH:mm[:ss[,SSS]][z yyyy-MM-dd