Commit dc9b7c0
Fix date math rounding to respect inclusive/exclusive bracket boundaries (#129)
* Fix date math rounding to respect inclusive/exclusive bracket boundaries
Previously, TwoPartFormatParser always passed isUpperLimit=false for the
start side and isUpperLimit=true for the end side of a range, regardless
of bracket type. This is only correct for inclusive [...] brackets.
Per Elasticsearch conventions, rounding behavior must change based on
whether each boundary is inclusive or exclusive:
- Inclusive min ([): rounds down (start of period) — gte semantics
- Exclusive min ({): rounds up (end of period) — gt semantics
- Inclusive max (]): rounds up (end of period) — lte semantics
- Exclusive max (}): rounds down (start of period) — lt semantics
This means [now/d TO now/d] correctly produces the entire day (start to
end), while {now/d TO now/d} collapses, and mixed brackets like
[now/d TO now/d} produce start-of-day to start-of-day.
Changes:
- Pre-scan closing bracket before parsing parts so isUpperLimit is known
upfront (uses a simple backwards char scan, no extra regex)
- Pass bracket-aware isUpperLimit to part parsers; wildcard parsers
still receive positional isUpperLimit (false=min, true=max) since they
use it for position semantics rather than rounding
- Allow mixed bracket pairs ([..}, {..]) per Elasticsearch Lucene syntax
- Add comprehensive tests for all four bracket combinations with /d, /M,
/h rounding and mixed date math operations
- Document rounding behavior in README with reference table and common
date range patterns
Ref: FoundatioFx/Foundatio.Lucene@a8426ab
Co-authored-by: Cursor <cursoragent@cursor.com>
* Address PR review feedback
- Simplify boolean ternary expressions per CodeQL: replace
`A ? false : B` with `A is not X && B` and `A ? true : B` with
`A is X || B` for the wildcard type checks
- Collapse inverted ranges from exclusive brackets instead of letting
DateTimeRange reorder bounds and unintentionally expand the range
- Update test comment to reflect the explicit collapse behavior
Co-authored-by: Cursor <cursoragent@cursor.com>
* Fixes bracket parsing logic for inclusivity
Corrects the logic for determining inclusive and exclusive date ranges based on brackets.
Improves the bracket parsing logic to handle null or empty content and bracket characters, ensuring accurate date range calculations.
Also fixes the IsValidBracketPair function to improve bracket validation.
---------
Co-authored-by: Cursor <cursoragent@cursor.com>1 parent ff789a9 commit dc9b7c0
4 files changed
Lines changed: 214 additions & 29 deletions
File tree
- src/Exceptionless.DateTimeExtensions/FormatParsers/FormatParsers
- tests/Exceptionless.DateTimeExtensions.Tests
- FormatParsers
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
70 | 70 | | |
71 | 71 | | |
72 | 72 | | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
| 109 | + | |
| 110 | + | |
| 111 | + | |
| 112 | + | |
| 113 | + | |
| 114 | + | |
| 115 | + | |
| 116 | + | |
| 117 | + | |
| 118 | + | |
| 119 | + | |
| 120 | + | |
| 121 | + | |
| 122 | + | |
| 123 | + | |
| 124 | + | |
| 125 | + | |
| 126 | + | |
| 127 | + | |
73 | 128 | | |
74 | 129 | | |
75 | 130 | | |
| |||
Lines changed: 57 additions & 24 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
28 | 28 | | |
29 | 29 | | |
30 | 30 | | |
31 | | - | |
32 | | - | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
33 | 35 | | |
34 | 36 | | |
35 | 37 | | |
36 | | - | |
37 | | - | |
| 38 | + | |
| 39 | + | |
38 | 40 | | |
39 | | - | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
40 | 69 | | |
41 | 70 | | |
42 | 71 | | |
43 | 72 | | |
44 | 73 | | |
45 | 74 | | |
46 | 75 | | |
47 | | - | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
48 | 80 | | |
49 | 81 | | |
50 | 82 | | |
| |||
65 | 97 | | |
66 | 98 | | |
67 | 99 | | |
68 | | - | |
| 100 | + | |
| 101 | + | |
69 | 102 | | |
70 | 103 | | |
71 | 104 | | |
| |||
77 | 110 | | |
78 | 111 | | |
79 | 112 | | |
80 | | - | |
81 | | - | |
82 | | - | |
83 | | - | |
| 113 | + | |
| 114 | + | |
| 115 | + | |
| 116 | + | |
| 117 | + | |
| 118 | + | |
| 119 | + | |
| 120 | + | |
84 | 121 | | |
85 | | - | |
| 122 | + | |
86 | 123 | | |
87 | 124 | | |
88 | 125 | | |
89 | | - | |
| 126 | + | |
| 127 | + | |
90 | 128 | | |
91 | | - | |
92 | | - | |
93 | | - | |
94 | | - | |
| 129 | + | |
95 | 130 | | |
96 | | - | |
97 | | - | |
| 131 | + | |
98 | 132 | | |
99 | 133 | | |
100 | | - | |
101 | | - | |
| 134 | + | |
102 | 135 | | |
103 | 136 | | |
104 | | - | |
105 | | - | |
106 | | - | |
| 137 | + | |
| 138 | + | |
| 139 | + | |
107 | 140 | | |
108 | 141 | | |
Lines changed: 86 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
352 | 352 | | |
353 | 353 | | |
354 | 354 | | |
| 355 | + | |
| 356 | + | |
| 357 | + | |
| 358 | + | |
| 359 | + | |
| 360 | + | |
| 361 | + | |
| 362 | + | |
| 363 | + | |
| 364 | + | |
| 365 | + | |
| 366 | + | |
| 367 | + | |
| 368 | + | |
| 369 | + | |
| 370 | + | |
| 371 | + | |
| 372 | + | |
| 373 | + | |
| 374 | + | |
| 375 | + | |
| 376 | + | |
| 377 | + | |
| 378 | + | |
| 379 | + | |
| 380 | + | |
| 381 | + | |
| 382 | + | |
| 383 | + | |
| 384 | + | |
| 385 | + | |
| 386 | + | |
| 387 | + | |
| 388 | + | |
| 389 | + | |
| 390 | + | |
| 391 | + | |
| 392 | + | |
| 393 | + | |
| 394 | + | |
| 395 | + | |
| 396 | + | |
| 397 | + | |
| 398 | + | |
| 399 | + | |
| 400 | + | |
| 401 | + | |
| 402 | + | |
| 403 | + | |
| 404 | + | |
| 405 | + | |
| 406 | + | |
| 407 | + | |
| 408 | + | |
| 409 | + | |
| 410 | + | |
| 411 | + | |
| 412 | + | |
| 413 | + | |
| 414 | + | |
| 415 | + | |
| 416 | + | |
| 417 | + | |
| 418 | + | |
| 419 | + | |
| 420 | + | |
| 421 | + | |
| 422 | + | |
| 423 | + | |
| 424 | + | |
| 425 | + | |
| 426 | + | |
| 427 | + | |
| 428 | + | |
| 429 | + | |
| 430 | + | |
| 431 | + | |
| 432 | + | |
| 433 | + | |
| 434 | + | |
| 435 | + | |
| 436 | + | |
| 437 | + | |
| 438 | + | |
| 439 | + | |
| 440 | + | |
355 | 441 | | |
Lines changed: 16 additions & 5 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
33 | 33 | | |
34 | 34 | | |
35 | 35 | | |
36 | | - | |
| 36 | + | |
37 | 37 | | |
38 | | - | |
| 38 | + | |
39 | 39 | | |
40 | 40 | | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
41 | 54 | | |
42 | 55 | | |
43 | 56 | | |
44 | 57 | | |
45 | | - | |
| 58 | + | |
46 | 59 | | |
47 | 60 | | |
48 | 61 | | |
49 | 62 | | |
50 | 63 | | |
51 | 64 | | |
52 | 65 | | |
53 | | - | |
54 | | - | |
55 | 66 | | |
56 | 67 | | |
57 | 68 | | |
| |||
0 commit comments