You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by ho...@apache.org on 2012/04/24 18:35:42 UTC
svn commit: r1329837 - in /lucene/dev/trunk/solr: ./
core/src/java/org/apache/solr/request/
core/src/java/org/apache/solr/schema/ core/src/java/org/apache/solr/util/
core/src/test/org/apache/solr/ core/src/test/org/apache/solr/request/
core/src/test/or...
Author: hossman
Date: Tue Apr 24 16:35:41 2012
New Revision: 1329837
URL: http://svn.apache.org/viewvc?rev=1329837&view=rev
Log:
SOLR-2690: New support for a "TZ" request param which overrides the TimeZone used when rounding Dates in DateMath expressions
Added:
lucene/dev/trunk/solr/core/src/java/org/apache/solr/util/TimeZoneUtils.java (with props)
lucene/dev/trunk/solr/core/src/test/org/apache/solr/util/TimeZoneUtilsTest.java (with props)
Modified:
lucene/dev/trunk/solr/CHANGES.txt
lucene/dev/trunk/solr/core/src/java/org/apache/solr/request/SimpleFacets.java
lucene/dev/trunk/solr/core/src/java/org/apache/solr/request/SolrRequestInfo.java
lucene/dev/trunk/solr/core/src/java/org/apache/solr/schema/DateField.java
lucene/dev/trunk/solr/core/src/java/org/apache/solr/util/DateMathParser.java
lucene/dev/trunk/solr/core/src/test/org/apache/solr/BasicFunctionalityTest.java
lucene/dev/trunk/solr/core/src/test/org/apache/solr/request/SimpleFacetsTest.java
lucene/dev/trunk/solr/core/src/test/org/apache/solr/util/DateMathParserTest.java
lucene/dev/trunk/solr/solrj/src/java/org/apache/solr/common/params/CommonParams.java
Modified: lucene/dev/trunk/solr/CHANGES.txt
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/CHANGES.txt?rev=1329837&r1=1329836&r2=1329837&view=diff
==============================================================================
--- lucene/dev/trunk/solr/CHANGES.txt (original)
+++ lucene/dev/trunk/solr/CHANGES.txt Tue Apr 24 16:35:41 2012
@@ -274,6 +274,11 @@ New Features
* SOLR-3363: Consolidated Exceptions in Analysis Factories so they only throw
InitalizationExceptions (Chris Male)
+* SOLR-2690: New support for a "TZ" request param which overrides the TimeZone
+ used when rounding Dates in DateMath expressions for the entire request
+ (all date range queries and date faceting is affected). The default TZ
+ is still UTC. (David Schlotfeldt, hossman)
+
Optimizations
----------------------
Modified: lucene/dev/trunk/solr/core/src/java/org/apache/solr/request/SimpleFacets.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/core/src/java/org/apache/solr/request/SimpleFacets.java?rev=1329837&r1=1329836&r2=1329837&view=diff
==============================================================================
--- lucene/dev/trunk/solr/core/src/java/org/apache/solr/request/SimpleFacets.java (original)
+++ lucene/dev/trunk/solr/core/src/java/org/apache/solr/request/SimpleFacets.java Tue Apr 24 16:35:41 2012
@@ -863,7 +863,7 @@ public class SimpleFacets {
}
final String gap = required.getFieldParam(f,FacetParams.FACET_DATE_GAP);
- final DateMathParser dmp = new DateMathParser(DateField.UTC, Locale.US);
+ final DateMathParser dmp = new DateMathParser();
final int minCount = params.getFieldInt(f,FacetParams.FACET_MINCOUNT, 0);
@@ -1387,7 +1387,7 @@ public class SimpleFacets {
}
@Override
public Date parseAndAddGap(Date value, String gap) throws java.text.ParseException {
- final DateMathParser dmp = new DateMathParser(DateField.UTC, Locale.US);
+ final DateMathParser dmp = new DateMathParser();
dmp.setNow(value);
return dmp.parseMath(gap);
}
Modified: lucene/dev/trunk/solr/core/src/java/org/apache/solr/request/SolrRequestInfo.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/core/src/java/org/apache/solr/request/SolrRequestInfo.java?rev=1329837&r1=1329836&r2=1329837&view=diff
==============================================================================
--- lucene/dev/trunk/solr/core/src/java/org/apache/solr/request/SolrRequestInfo.java (original)
+++ lucene/dev/trunk/solr/core/src/java/org/apache/solr/request/SolrRequestInfo.java Tue Apr 24 16:35:41 2012
@@ -18,12 +18,15 @@
package org.apache.solr.request;
import org.apache.solr.common.SolrException;
+import org.apache.solr.common.params.CommonParams;
import org.apache.solr.core.SolrCore;
import org.apache.solr.handler.component.ResponseBuilder;
import org.apache.solr.response.SolrQueryResponse;
+import org.apache.solr.util.TimeZoneUtils;
import java.io.Closeable;
import java.util.Date;
+import java.util.TimeZone;
import java.util.LinkedList;
import java.util.List;
@@ -34,6 +37,7 @@ public class SolrRequestInfo {
protected SolrQueryRequest req;
protected SolrQueryResponse rsp;
protected Date now;
+ protected TimeZone tz;
protected ResponseBuilder rb;
protected List<Closeable> closeHooks;
@@ -79,7 +83,7 @@ public class SolrRequestInfo {
if (now != null) return now;
long ms = 0;
- String nowStr = req.getParams().get("NOW");
+ String nowStr = req.getParams().get(CommonParams.NOW);
if (nowStr != null) {
ms = Long.parseLong(nowStr);
@@ -91,6 +95,22 @@ public class SolrRequestInfo {
return now;
}
+ /** The TimeZone specified by the request, or null if none was specified */
+ public TimeZone getClientTimeZone() {
+
+ if (tz == null) {
+ String tzStr = req.getParams().get(CommonParams.TZ);
+ if (tzStr != null) {
+ tz = TimeZoneUtils.getTimeZone(tzStr);
+ if (null == tz) {
+ throw new SolrException(SolrException.ErrorCode.BAD_REQUEST,
+ "Solr JVM does not support TZ: " + tzStr);
+ }
+ }
+ }
+ return tz;
+ }
+
public SolrQueryRequest getReq() {
return req;
}
Modified: lucene/dev/trunk/solr/core/src/java/org/apache/solr/schema/DateField.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/core/src/java/org/apache/solr/schema/DateField.java?rev=1329837&r1=1329836&r2=1329837&view=diff
==============================================================================
--- lucene/dev/trunk/solr/core/src/java/org/apache/solr/schema/DateField.java (original)
+++ lucene/dev/trunk/solr/core/src/java/org/apache/solr/schema/DateField.java Tue Apr 24 16:35:41 2012
@@ -105,12 +105,18 @@ public class DateField extends Primitive
public static TimeZone UTC = TimeZone.getTimeZone("UTC");
- /* :TODO: let Locale/TimeZone come from init args for rounding only */
-
- /** TimeZone for DateMath (UTC) */
- protected static final TimeZone MATH_TZ = UTC;
- /** Locale for DateMath (Locale.US) */
- protected static final Locale MATH_LOCALE = Locale.US;
+ /**
+ * No longer used
+ * @deprecated use DateMathParser.DEFAULT_MATH_TZ
+ * @see DateMathParser#DEFAULT_MATH_TZ
+ */
+ protected static final TimeZone MATH_TZ = DateMathParser.DEFAULT_MATH_TZ;
+ /**
+ * No longer used
+ * @deprecated use DateMathParser.DEFAULT_MATH_LOCALE
+ * @see DateMathParser#DEFAULT_MATH_LOCALE
+ */
+ protected static final Locale MATH_LOCALE = DateMathParser.DEFAULT_MATH_LOCALE;
/**
* Fixed TimeZone (UTC) needed for parsing/formating Dates in the
@@ -146,7 +152,7 @@ public class DateField extends Primitive
*/
public Date parseMath(Date now, String val) {
String math = null;
- final DateMathParser p = new DateMathParser(MATH_TZ, MATH_LOCALE);
+ final DateMathParser p = new DateMathParser();
if (null != now) p.setNow(now);
@@ -296,7 +302,7 @@ public class DateField extends Primitive
*/
public Date parseMathLenient(Date now, String val, SolrQueryRequest req) {
String math = null;
- final DateMathParser p = new DateMathParser(MATH_TZ, MATH_LOCALE);
+ final DateMathParser p = new DateMathParser();
if (null != now) p.setNow(now);
Modified: lucene/dev/trunk/solr/core/src/java/org/apache/solr/util/DateMathParser.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/core/src/java/org/apache/solr/util/DateMathParser.java?rev=1329837&r1=1329836&r2=1329837&view=diff
==============================================================================
--- lucene/dev/trunk/solr/core/src/java/org/apache/solr/util/DateMathParser.java (original)
+++ lucene/dev/trunk/solr/core/src/java/org/apache/solr/util/DateMathParser.java Tue Apr 24 16:35:41 2012
@@ -78,6 +78,13 @@ import java.util.regex.Pattern;
*
*/
public class DateMathParser {
+
+ public static TimeZone UTC = TimeZone.getTimeZone("UTC");
+
+ /** Default TimeZone for DateMath rounding (UTC) */
+ public static final TimeZone DEFAULT_MATH_TZ = UTC;
+ /** Default Locale for DateMath rounding (Locale.US) */
+ public static final Locale DEFAULT_MATH_LOCALE = Locale.US;
/**
* A mapping from (uppercased) String labels idenyifying time units,
@@ -101,6 +108,10 @@ public class DateMathParser {
// because of complexity in rounding down to the nearest week
// arround a month/year boundry.
// (Not to mention: it's not clear what people would *expect*)
+ //
+ // If we consider adding some time of "week" support, then
+ // we probably need to change "Locale loc" to default to something
+ // from a param via SolrRequestInfo as well.
Map<String,Integer> units = new HashMap<String,Integer>(13);
units.put("YEAR", Calendar.YEAR);
@@ -193,21 +204,53 @@ public class DateMathParser {
private Date now;
/**
- * @param tz The TimeZone used for rounding (to determine when hours/days begin)
- * @param l The Locale used for rounding (to determine when weeks begin)
+ * Default constructor that assumes UTC should be used for rounding unless
+ * otherwise specified in the SolrRequestInfo
+ *
+ * @see #DEFAULT_MATH_TZ
+ * @see #DEFAULT_MATH_LOCALE
+ */
+ public DateMathParser() {
+ this(null, DEFAULT_MATH_LOCALE);
+
+ }
+
+ /**
+ * @param tz The TimeZone used for rounding (to determine when hours/days begin). If null, then this method defaults to the value dicated by the SolrRequestInfo if it
+ * exists -- otherwise it uses UTC.
+ * @param l The Locale used for rounding (to determine when weeks begin). If null, then this method defaults to en_US.
+ * @see #DEFAULT_MATH_TZ
+ * @see #DEFAULT_MATH_LOCALE
* @see Calendar#getInstance(TimeZone,Locale)
+ * @see SolrRequestInfo#getClientTimeZone
*/
public DateMathParser(TimeZone tz, Locale l) {
- zone = tz;
- loc = l;
+ loc = (null != l) ? l : DEFAULT_MATH_LOCALE;
+ if (null == tz) {
+ SolrRequestInfo reqInfo = SolrRequestInfo.getRequestInfo();
+ tz = (null != reqInfo) ? reqInfo.getClientTimeZone() : DEFAULT_MATH_TZ;
+ }
+ zone = (null != tz) ? tz : DEFAULT_MATH_TZ;
}
- /** Redefines this instance's concept of "now" */
+ /**
+ * Defines this instance's concept of "now".
+ * @see #getNow
+ */
public void setNow(Date n) {
now = n;
}
- /** Returns a cloned of this instance's concept of "now" */
+ /**
+ * Returns a cloned of this instance's concept of "now".
+ *
+ * If setNow was never called (or if null was specified) then this method
+ * first defines 'now' as the value dictated by the SolrRequestInfo if it
+ * exists -- otherwise it uses a new Date instance at the moment getNow()
+ * is first called.
+ * @see #setNow
+ * @see SolrRequestInfo#getNow
+ */
public Date getNow() {
if (now == null) {
SolrRequestInfo reqInfo = SolrRequestInfo.getRequestInfo();
Added: lucene/dev/trunk/solr/core/src/java/org/apache/solr/util/TimeZoneUtils.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/core/src/java/org/apache/solr/util/TimeZoneUtils.java?rev=1329837&view=auto
==============================================================================
--- lucene/dev/trunk/solr/core/src/java/org/apache/solr/util/TimeZoneUtils.java (added)
+++ lucene/dev/trunk/solr/core/src/java/org/apache/solr/util/TimeZoneUtils.java Tue Apr 24 16:35:41 2012
@@ -0,0 +1,86 @@
+/**
+ * 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.util.TimeZone;
+import java.util.Set;
+import java.util.HashSet;
+import java.util.Collections;
+import java.util.Arrays;
+
+import java.util.regex.Pattern;
+import java.util.regex.Matcher;
+
+/**
+ * Simple utilities for working with TimeZones
+ * @see java.util.TimeZone
+ */
+public final class TimeZoneUtils {
+
+ private TimeZoneUtils() {
+ // :NOOP:
+ }
+
+ /**
+ * An immutable Set of all TimeZone IDs supported by the TimeZone class
+ * at the moment the TimeZoneUtils was initialized.
+ *
+ * @see TimeZone#getAvailableIDs
+ */
+ public static final Set<String> KNOWN_TIMEZONE_IDS
+ = Collections.unmodifiableSet(new HashSet<String>
+ (Arrays.asList(TimeZone.getAvailableIDs())));
+
+ /**
+ * This method is provided as a replacement for TimeZone.getTimeZone but
+ * with out the anoying behavior of returning "GMT" for gibberish input.
+ * <p>
+ * This method will return null unless the input is either:
+ * </p>
+ * <ul>
+ * <li>Included in the set of known TimeZone IDs
+ * <li>A "CustomID" specified as a numeric offset from "GMT"</li>
+ * </ul>
+ *
+ * @param ID Either a TimeZone ID found in KNOWN_TIMEZONE_IDS, or a "CustomID" specified as a GMT offset.
+ * @return A TImeZone object corrisponding to the input, or null if no such TimeZone is supported.
+ * @see #KNOWN_TIMEZONE_IDS
+ * @see TimeZone
+ */
+ public static final TimeZone getTimeZone(final String ID) {
+ if (null == ID) return null;
+ if (KNOWN_TIMEZONE_IDS.contains(ID)) return TimeZone.getTimeZone(ID);
+
+ Matcher matcher = CUSTOM_ID_REGEX.matcher(ID);
+ if (matcher.matches()) {
+ int hour = Integer.parseInt(matcher.group(1));
+ if (hour < 0 || 23 < hour) return null;
+
+ final String minStr = matcher.group(2);
+ if (null != minStr) {
+ int min = Integer.parseInt(minStr);
+ if (min < 0 || 59 < min) return null;
+ }
+ return TimeZone.getTimeZone(ID);
+ }
+ return null;
+ }
+
+ private static Pattern CUSTOM_ID_REGEX = Pattern.compile("GMT(?:\\+|\\-)(\\d{1,2})(?::?(\\d{2}))?");
+
+}
Modified: lucene/dev/trunk/solr/core/src/test/org/apache/solr/BasicFunctionalityTest.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/core/src/test/org/apache/solr/BasicFunctionalityTest.java?rev=1329837&r1=1329836&r2=1329837&view=diff
==============================================================================
--- lucene/dev/trunk/solr/core/src/test/org/apache/solr/BasicFunctionalityTest.java (original)
+++ lucene/dev/trunk/solr/core/src/test/org/apache/solr/BasicFunctionalityTest.java Tue Apr 24 16:35:41 2012
@@ -690,6 +690,19 @@ public class BasicFunctionalityTest exte
assertQ("check count for near stuff",
req("q", "bday:[NOW-1MONTH TO NOW+2HOURS]"), "*[count(//doc)=4]");
+ assertQ("check counts using fixed NOW",
+ req("q", "bday:[NOW/DAY TO NOW/DAY+1DAY]",
+ "NOW", "205369736000" // 1976-07-04T23:08:56.235Z
+ ),
+ "*[count(//doc)=1]");
+
+ assertQ("check counts using fixed NOW and TZ rounding",
+ req("q", "bday:[NOW/DAY TO NOW/DAY+1DAY]",
+ "TZ", "GMT-23",
+ "NOW", "205369736000" // 1976-07-04T23:08:56.235Z
+ ),
+ "*[count(//doc)=0]");
+
}
public void testDateRoundtrip() {
Modified: lucene/dev/trunk/solr/core/src/test/org/apache/solr/request/SimpleFacetsTest.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/core/src/test/org/apache/solr/request/SimpleFacetsTest.java?rev=1329837&r1=1329836&r2=1329837&view=diff
==============================================================================
--- lucene/dev/trunk/solr/core/src/test/org/apache/solr/request/SimpleFacetsTest.java (original)
+++ lucene/dev/trunk/solr/core/src/test/org/apache/solr/request/SimpleFacetsTest.java Tue Apr 24 16:35:41 2012
@@ -22,16 +22,23 @@ import org.apache.solr.SolrTestCaseJ4;
import org.apache.solr.common.SolrException;
import org.apache.solr.common.params.ModifiableSolrParams;
import org.apache.solr.schema.SchemaField;
+import org.apache.solr.util.TimeZoneUtils;
import org.junit.BeforeClass;
import org.junit.Test;
+import java.util.Arrays;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
+import java.util.Set;
+import java.util.HashSet;
+import java.util.TimeZone;
public class SimpleFacetsTest extends SolrTestCaseJ4 {
+
+
@BeforeClass
public static void beforeClass() throws Exception {
initCore("solrconfig.xml","schema.xml");
@@ -1029,6 +1036,100 @@ public class SimpleFacetsTest extends So
}
@Test
+ public void testDateFacetsWithTz() {
+ for (String field : new String[] { "a_tdt", "a_pdt"}) {
+ for (boolean rangeType : new boolean[] { true, false }) {
+ helpTestDateFacetsWithTz(field, rangeType);
+ }
+ }
+ }
+
+ private void helpTestDateFacetsWithTz(final String fieldName,
+ final boolean rangeMode) {
+ final String p = rangeMode ? "facet.range" : "facet.date";
+ final String b = rangeMode ? "facet_ranges" : "facet_dates";
+ final String f = fieldName;
+ final String c = (rangeMode ? "/lst[@name='counts']" : "");
+ final String pre = "//lst[@name='"+b+"']/lst[@name='"+f+"']" + c;
+ final String meta = pre + (rangeMode ? "/../" : "");
+
+ final String TZ = "America/Los_Angeles";
+ assumeTrue("Test requires JVM to know about about TZ: " + TZ,
+ TimeZoneUtils.KNOWN_TIMEZONE_IDS.contains(TZ));
+
+ assertQ("checking facet counts for fixed now, using TZ: " + TZ,
+ req( "q", "*:*"
+ ,"rows", "0"
+ ,"facet", "true"
+ ,"NOW", "205078333000" // 1976-07-01T14:12:13.000Z
+ ,"TZ", TZ
+ ,p, f
+ ,p+".start", "NOW/MONTH"
+ ,p+".end", "NOW/MONTH+15DAYS"
+ ,p+".gap", "+1DAY"
+ ,p+".other", "all"
+ ,p+".include", "lower"
+ )
+ // 15 days + pre+post+inner = 18
+ ,"*[count("+pre+"/int)="+(rangeMode ? 15 : 18)+"]"
+ ,pre+"/int[@name='1976-07-01T07:00:00Z'][.='0']"
+ ,pre+"/int[@name='1976-07-02T07:00:00Z'][.='0']"
+ ,pre+"/int[@name='1976-07-03T07:00:00Z'][.='1' ]"
+ ,pre+"/int[@name='1976-07-04T07:00:00Z'][.='1' ]"
+ ,pre+"/int[@name='1976-07-05T07:00:00Z'][.='1' ]"
+ ,pre+"/int[@name='1976-07-06T07:00:00Z'][.='1' ]"
+ ,pre+"/int[@name='1976-07-07T07:00:00Z'][.='0']"
+ ,pre+"/int[@name='1976-07-08T07:00:00Z'][.='0']"
+ ,pre+"/int[@name='1976-07-09T07:00:00Z'][.='0']"
+ ,pre+"/int[@name='1976-07-10T07:00:00Z'][.='0']"
+ ,pre+"/int[@name='1976-07-11T07:00:00Z'][.='0']"
+ ,pre+"/int[@name='1976-07-12T07:00:00Z'][.='1' ]"
+ ,pre+"/int[@name='1976-07-13T07:00:00Z'][.='1' ]"
+ ,pre+"/int[@name='1976-07-14T07:00:00Z'][.='0']"
+ ,pre+"/int[@name='1976-07-15T07:00:00Z'][.='1' ]"
+ //
+ ,meta+"/int[@name='before' ][.='2']"
+ ,meta+"/int[@name='after' ][.='1']"
+ ,meta+"/int[@name='between'][.='7']"
+ );
+
+ // NOTE: the counts should all be zero, what we really care about
+ // is that the computed lower bounds take into account DST change
+ assertQ("checking facet counts arround DST change for TZ: " + TZ,
+ req( "q", "*:*"
+ ,"rows", "0"
+ ,"facet", "true"
+ ,"NOW", "1288606136000" // 2010-11-01T10:08:56.235Z
+ ,"TZ", TZ
+ ,p, f
+ ,p+".start", "NOW/MONTH"
+ ,p+".end", "NOW/MONTH+15DAYS"
+ ,p+".gap", "+1DAY"
+ ,p+".other", "all"
+ ,p+".include", "lower"
+ )
+ // 15 days + pre+post+inner = 18
+ ,"*[count("+pre+"/int)="+(rangeMode ? 15 : 18)+"]"
+ ,pre+"/int[@name='2010-11-01T07:00:00Z'][.='0']"
+ ,pre+"/int[@name='2010-11-02T07:00:00Z'][.='0']"
+ ,pre+"/int[@name='2010-11-03T07:00:00Z'][.='0']"
+ ,pre+"/int[@name='2010-11-04T07:00:00Z'][.='0']"
+ ,pre+"/int[@name='2010-11-05T07:00:00Z'][.='0']"
+ ,pre+"/int[@name='2010-11-06T07:00:00Z'][.='0']"
+ ,pre+"/int[@name='2010-11-07T07:00:00Z'][.='0']"
+ ,pre+"/int[@name='2010-11-08T08:00:00Z'][.='0']" // BOOM!
+ ,pre+"/int[@name='2010-11-09T08:00:00Z'][.='0']"
+ ,pre+"/int[@name='2010-11-10T08:00:00Z'][.='0']"
+ ,pre+"/int[@name='2010-11-11T08:00:00Z'][.='0']"
+ ,pre+"/int[@name='2010-11-12T08:00:00Z'][.='0']"
+ ,pre+"/int[@name='2010-11-13T08:00:00Z'][.='0']"
+ ,pre+"/int[@name='2010-11-14T08:00:00Z'][.='0']"
+ ,pre+"/int[@name='2010-11-15T08:00:00Z'][.='0']"
+ );
+
+ }
+
+ @Test
public void testNumericRangeFacetsTrieFloat() {
helpTestFractionalNumberRangeFacets("range_facet_f");
}
Modified: lucene/dev/trunk/solr/core/src/test/org/apache/solr/util/DateMathParserTest.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/core/src/test/org/apache/solr/util/DateMathParserTest.java?rev=1329837&r1=1329836&r2=1329837&view=diff
==============================================================================
--- lucene/dev/trunk/solr/core/src/test/org/apache/solr/util/DateMathParserTest.java (original)
+++ lucene/dev/trunk/solr/core/src/test/org/apache/solr/util/DateMathParserTest.java Tue Apr 24 16:35:41 2012
@@ -26,6 +26,9 @@ import java.util.Calendar;
import java.util.Date;
import java.util.TimeZone;
import java.util.Locale;
+import java.util.Arrays;
+import java.util.Set;
+import java.util.HashSet;
import java.util.Map;
import java.util.HashMap;
@@ -255,7 +258,57 @@ public class DateMathParserTest extends
}
-
+
+ public void testParseMathTz() throws Exception {
+
+ final String PLUS_TZS = "America/Los_Angeles";
+ final String NEG_TZS = "Europe/Paris";
+
+ assumeTrue("Test requires JVM to know about about TZ: " + PLUS_TZS,
+ TimeZoneUtils.KNOWN_TIMEZONE_IDS.contains(PLUS_TZS));
+ assumeTrue("Test requires JVM to know about about TZ: " + NEG_TZS,
+ TimeZoneUtils.KNOWN_TIMEZONE_IDS.contains(NEG_TZS));
+
+ // US, Positive Offset with DST
+
+ TimeZone tz = TimeZone.getTimeZone(PLUS_TZS);
+ DateMathParser p = new DateMathParser(tz, Locale.US);
+
+ p.setNow(parser.parse("2001-07-04T12:08:56.235"));
+
+ // No-Op
+ assertMath("2001-07-04T12:08:56.235", p, "");
+
+ assertMath("2001-07-04T12:08:56.000", p, "/SECOND");
+ assertMath("2001-07-04T12:08:00.000", p, "/MINUTE");
+ assertMath("2001-07-04T12:00:00.000", p, "/HOUR");
+ assertMath("2001-07-04T07:00:00.000", p, "/DAY");
+ assertMath("2001-07-01T07:00:00.000", p, "/MONTH");
+ // no DST in jan
+ assertMath("2001-01-01T08:00:00.000", p, "/YEAR");
+ // no DST in nov 2001
+ assertMath("2001-11-04T08:00:00.000", p, "+4MONTH/DAY");
+ // yes DST in nov 2010
+ assertMath("2010-11-04T07:00:00.000", p, "+9YEAR+4MONTH/DAY");
+
+ // France, Negative Offset with DST
+
+ tz = TimeZone.getTimeZone(NEG_TZS);
+ p = new DateMathParser(tz, Locale.US);
+ p.setNow(parser.parse("2001-07-04T12:08:56.235"));
+
+ assertMath("2001-07-04T12:08:56.000", p, "/SECOND");
+ assertMath("2001-07-04T12:08:00.000", p, "/MINUTE");
+ assertMath("2001-07-04T12:00:00.000", p, "/HOUR");
+ assertMath("2001-07-03T22:00:00.000", p, "/DAY");
+ assertMath("2001-06-30T22:00:00.000", p, "/MONTH");
+ // no DST in dec
+ assertMath("2000-12-31T23:00:00.000", p, "/YEAR");
+ // no DST in nov
+ assertMath("2001-11-03T23:00:00.000", p, "+4MONTH/DAY");
+
+ }
+
public void testParseMathExceptions() throws Exception {
DateMathParser p = new DateMathParser(UTC, Locale.US);
Added: lucene/dev/trunk/solr/core/src/test/org/apache/solr/util/TimeZoneUtilsTest.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/core/src/test/org/apache/solr/util/TimeZoneUtilsTest.java?rev=1329837&view=auto
==============================================================================
--- lucene/dev/trunk/solr/core/src/test/org/apache/solr/util/TimeZoneUtilsTest.java (added)
+++ lucene/dev/trunk/solr/core/src/test/org/apache/solr/util/TimeZoneUtilsTest.java Tue Apr 24 16:35:41 2012
@@ -0,0 +1,102 @@
+/**
+ * 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 org.apache.lucene.util.LuceneTestCase;
+import org.apache.lucene.util._TestUtil;
+
+import java.util.Set;
+import java.util.HashSet;
+import java.util.Random;
+import java.util.TimeZone;
+import java.util.Locale;
+
+public class TimeZoneUtilsTest extends LuceneTestCase {
+
+ public void testValidIds() throws Exception {
+
+ final Set<String> idsTested = new HashSet<String>();
+
+ // brain dead: anything the JVM supports, should work
+ for (String validId : TimeZone.getAvailableIDs()) {
+ assertTrue(validId + " not found in list of known ids",
+ TimeZoneUtils.KNOWN_TIMEZONE_IDS.contains(validId));
+
+ final TimeZone expected = TimeZone.getTimeZone(validId);
+ final TimeZone actual = TimeZoneUtils.getTimeZone(validId);
+ assertEquals(validId, expected, actual);
+
+ idsTested.add(validId);
+ }
+
+ assertEquals("TimeZone.getAvailableIDs vs TimeZoneUtils.KNOWN_TIMEZONE_IDS",
+ TimeZoneUtils.KNOWN_TIMEZONE_IDS.size(), idsTested.size());
+ }
+
+ public void testCustom() throws Exception {
+
+ for (String input : new String[] {"GMT+08","GMT+8",
+ "GMT-0800","GMT-08:00",
+ "GMT+23", "GMT+2300"}) {
+ assertEquals(input,
+ TimeZone.getTimeZone(input),
+ TimeZoneUtils.getTimeZone(input));
+ }
+ }
+
+ public void testInvalidInput() throws Exception {
+
+ final String giberish = "giberish";
+ assumeFalse("This test assumes that " + giberish + " is not a valid tz id",
+ TimeZoneUtils.KNOWN_TIMEZONE_IDS.contains(giberish));
+ assertNull(giberish, TimeZoneUtils.getTimeZone(giberish));
+
+
+ for (String malformed : new String[] {"GMT+72", "GMT0800",
+ "GMT+2400" , "GMT+24:00",
+ "GMT+11-30" , "GMT+11:-30",
+ "GMT+0080" , "GMT+00:80"}) {
+ assertNull(malformed, TimeZoneUtils.getTimeZone(malformed));
+ }
+ }
+
+
+
+ public void testRandom() throws Exception {
+ final String ONE_DIGIT = "%1d";
+ final String TWO_DIGIT = "%02d";
+
+ final Random r = random();
+ final int iters = atLeast(r, 50);
+ for (int i = 0; i <= iters; i++) {
+ int hour = _TestUtil.nextInt(r, 0, 23);
+ int min = _TestUtil.nextInt(r, 0, 59);
+
+ String hours = String.format(Locale.US,
+ (r.nextBoolean() ? ONE_DIGIT : TWO_DIGIT),
+ hour);
+ String mins = String.format(Locale.US, TWO_DIGIT, min);
+ String input = "GMT" + (r.nextBoolean()?"+":"-")
+ + hours + (r.nextBoolean() ? "" : ((r.nextBoolean()?":":"") + mins));
+ assertEquals(input,
+ TimeZone.getTimeZone(input),
+ TimeZoneUtils.getTimeZone(input));
+ }
+ }
+}
+
Modified: lucene/dev/trunk/solr/solrj/src/java/org/apache/solr/common/params/CommonParams.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/solrj/src/java/org/apache/solr/common/params/CommonParams.java?rev=1329837&r1=1329836&r2=1329837&view=diff
==============================================================================
--- lucene/dev/trunk/solr/solrj/src/java/org/apache/solr/common/params/CommonParams.java (original)
+++ lucene/dev/trunk/solr/solrj/src/java/org/apache/solr/common/params/CommonParams.java Tue Apr 24 16:35:41 2012
@@ -25,6 +25,20 @@ import java.util.Locale;
*/
public interface CommonParams {
+ /**
+ * Override for the concept of "NOW" to be used throughout this request,
+ * expressed as milliseconds since epoch. This is primarily used in
+ * distributed search to ensure consistent time values are used across
+ * multiple sub-requests.
+ */
+ public static final String NOW = "NOW";
+
+ /**
+ * Specifies the TimeZone used by the client for the purposes of
+ * any DateMath rounding that may take place when executing the request
+ */
+ public static final String TZ = "TZ";
+
/** the query type - which query handler should handle the request */
public static final String QT ="qt";