|
37 | 37 | import java.time.ZoneId; |
38 | 38 | import java.time.ZoneOffset; |
39 | 39 | import java.time.ZonedDateTime; |
| 40 | +import java.time.temporal.Temporal; |
40 | 41 | import java.util.ArrayList; |
41 | 42 | import java.util.Arrays; |
42 | 43 | import java.util.List; |
43 | 44 | import java.util.Set; |
44 | 45 | import java.util.function.BiFunction; |
| 46 | +import java.util.function.LongSupplier; |
45 | 47 |
|
46 | 48 | /** Enum defining the type of range */ |
47 | 49 | public enum RangeType { |
@@ -293,28 +295,22 @@ public Query rangeQuery( |
293 | 295 |
|
294 | 296 | DateMathParser dateMathParser = (parser == null) ? DateFieldMapper.DEFAULT_DATE_TIME_FORMATTER.toDateMathParser() : parser; |
295 | 297 | boolean roundUp = includeLower == false; // using "gt" should round lower bound up |
296 | | - Long low = lowerTerm == null |
297 | | - ? minValue() |
298 | | - : dateMathParser.parse( |
299 | | - lowerTerm instanceof BytesRef ? ((BytesRef) lowerTerm).utf8ToString() : lowerTerm.toString(), |
300 | | - context::nowInMillis, |
301 | | - roundUp, |
302 | | - zone |
303 | | - ).toEpochMilli(); |
| 298 | + Long low = lowerTerm == null ? minValue() : parseRangeTerm(dateMathParser, lowerTerm, zone, roundUp, context::nowInMillis); |
304 | 299 |
|
305 | 300 | roundUp = includeUpper; // using "lte" should round upper bound up |
306 | | - Long high = upperTerm == null |
307 | | - ? maxValue() |
308 | | - : dateMathParser.parse( |
309 | | - upperTerm instanceof BytesRef ? ((BytesRef) upperTerm).utf8ToString() : upperTerm.toString(), |
310 | | - context::nowInMillis, |
311 | | - roundUp, |
312 | | - zone |
313 | | - ).toEpochMilli(); |
314 | | - |
| 301 | + Long high = upperTerm == null ? maxValue() : parseRangeTerm(dateMathParser, upperTerm, zone, roundUp, context::nowInMillis); |
315 | 302 | return createRangeQuery(field, hasDocValues, low, high, includeLower, includeUpper, relation); |
316 | 303 | } |
317 | 304 |
|
| 305 | + private static long parseRangeTerm(DateMathParser parser, Object term, ZoneId zone, boolean roundUp, LongSupplier nowInMillis) { |
| 306 | + String termString = term instanceof BytesRef ? ((BytesRef) term).utf8ToString() : term.toString(); |
| 307 | + // `roundUp` may only be used if the term is not a Temporal object. LocalTime#toString() and similar will output |
| 308 | + // the shortest possible representation and might omit seconds, milliseconds, etc. |
| 309 | + // That interferes badly with the behavior of the roundup parser leading to unexpected results. |
| 310 | + boolean mayRoundUp = (term instanceof Temporal) == false; |
| 311 | + return parser.parse(termString, nowInMillis, roundUp && mayRoundUp, zone).toEpochMilli(); |
| 312 | + } |
| 313 | + |
318 | 314 | @Override |
319 | 315 | public Query withinQuery(String field, Object from, Object to, boolean includeLower, boolean includeUpper) { |
320 | 316 | return LONG.withinQuery(field, from, to, includeLower, includeUpper); |
|
0 commit comments