# DateMath: Fix semantics of rounding with inclusive/exclusive ranges. #8556

Closed
wants to merge 1 commit into from

## Conversation

Projects
None yet
4 participants
Member

### rjernst commented Nov 19, 2014

 Date math rounding currently works by rounding the date up or down based on the scope of the rounding. For example, if you have the date `2009-12-24||/d` it will round down to the inclusive lower end `2009-12-24T00:00:00.000` and round up to the non-inclusive date `2009-12-25T00:00:00.000`. The range endpoint semantics work as follows: `gt` - round D down, and use > that value `gte` - round D down, and use >= that value `lt` - round D down, and use < `lte` - round D up, and use <= There are 2 problems with these semantics: `lte` ends up including the upper value, which should be non-inclusive `gt` only excludes the beginning of the date, not the entire rounding scope This change makes the range endpoint semantics symmetrical. First, it changes the parser to round up and down using the first (same as before) and last (1 ms less than before) values of the rounding scope. This makes both rounded endpoints inclusive. The range endpoint semantics are then as follows: `gt` - round D up, and use > that value `gte` - round D down, and use >= that value `lt` - round D down, and use < that value `lte` - round D up, and use <= that value closes #8424
``` DateMath: Fix semantics of rounding with inclusive/exclusive ranges. ```
```Date math rounding currently works by rounding the date up or down based
on the scope of the rounding.  For example, if you have the date
`2009-12-24||/d` it will round down to the inclusive lower end
`2009-12-24T00:00:00.000` and round up to the non-inclusive date
`2009-12-25T00:00:00.000`.

The range endpoint semantics work as follows:
gt - round D down, and use > that value
gte - round D down, and use >= that value
lt - round D down, and use <
lte - round D up, and use <=

There are 2 problems with these semantics:
1. lte ends up including the upper value, which should be non-inclusive
2. gt only excludes the beginning of the date, not the entire rounding scope

This change makes the range endpoint semantics symmetrical.  First, it
changes the parser to round up and down using the first (same as before)
and last (1 ms less than before) values of the rounding scope.  This
makes both rounded endpoints inclusive. The range endpoint semantics
are then as follows:
gt - round D up, and use > that value
gte - round D down, and use >= that value
lt - round D down, and use < that value
lte - round D up, and use <= that value

closes #8424```
``` 1fc8eda ```

### martijnvg reviewed Nov 20, 2014

 long now = context == null ? System.currentTimeMillis() : context.nowInMillis(); DateMathParser dateParser = dateMathParser; if (forcedDateParser != null) { dateParser = forcedDateParser; } long time = includeUpper && roundCeil ? dateParser.parseRoundCeil(value, now, zone) : dateParser.parse(value, now, zone); return time; boolean roundUp = inclusive && roundCeil; // TODO: what is roundCeil??

#### martijnvg Nov 20, 2014

Member

This is a hard override (via index.mapping.date.round_ceil setting, which default to true) to disallow rounding up. Not sure if this actuall set to false, seems undesired to me.

#### rjernst Nov 20, 2014

Author Member

I will open a separate issue to deal with this odd setting.

Contributor

+1

Member

 LGTM
Contributor

 LGTM^2

### rjernst added a commit that referenced this pull request Nov 21, 2014

``` Fix compile error from bad merge in #8556 ```
``` 4a3afcc ```

### rjernst added a commit that referenced this pull request Nov 21, 2014

``` DateMath: Fix semantics of rounding with inclusive/exclusive ranges. ```
```Date math rounding currently works by rounding the date up or down based
on the scope of the rounding.  For example, if you have the date
`2009-12-24||/d` it will round down to the inclusive lower end
`2009-12-24T00:00:00.000` and round up to the non-inclusive date
`2009-12-25T00:00:00.000`.

The range endpoint semantics work as follows:
* `gt` - round D down, and use > that value
* `gte` - round D down, and use >= that value
* `lt` - round D down, and use <
* `lte` - round D up, and use <=

There are 2 problems with these semantics:
* `lte` ends up including the upper value, which should be non-inclusive
* `gt` only excludes the beginning of the date, not the entire rounding scope

This change makes the range endpoint semantics symmetrical.  First, it
changes the parser to round up and down using the first (same as before)
and last (1 ms less than before) values of the rounding scope.  This
makes both rounded endpoints inclusive. The range endpoint semantics
are then as follows:
* `gt` - round D up, and use > that value
* `gte` - round D down, and use >= that value
* `lt` - round D down, and use < that value
* `lte` - round D up, and use <= that value

closes #8424
closes #8556```
``` f3202ba ```

### rjernst added a commit that referenced this pull request Nov 21, 2014

``` Fix test failures caused by #8556 ```
``` 40598a5 ```

### rjernst added a commit that referenced this pull request Nov 21, 2014

``` Fix test failures caused by #8556 ```
``` 309a922 ```

Merged

### rjernst added a commit to rjernst/elasticsearch that referenced this pull request Dec 15, 2014

``` Settings: Remove `mapping.date.round_ceil` setting for date math parsing ```
```The setting `mapping.date.round_ceil` (and the undocumented setting
`index.mapping.date.parse_upper_inclusive`) affect how date ranges using
`lte` are parsed.  In elastic#8556 the semantics of date rounding were
solidified, eliminating the need to have different parsing functions
whether the date is inclusive or exclusive.

This change removes these legacy settings and improves the tests
for the date math parser (now at 100% coverage!). It also removes the
unnecessary function `DateMathParser.parseTimeZone` for which
the existing `DateTimeZone.forID` handles all use cases.

Any user previously using these settings can refer to the changed
semantics and change their query accordingly. This is a breaking change
because even dates without datemath previously used the different
parsing functions depending on context.

closes elastic#8598
closes elastic#8889```
``` 3728728 ```

Closed