Skip to content

Commit 8391b51

Browse files
author
Christoph Büscher
committed
DateMath: Fix using time zone when rounding.
Currently rounding in DateMathParser This always done in UTC, even when another time zone is specified. This is fixed by passing the time zone down to the rounding logic when it is specified. Closes #9814 Closes #9885
1 parent 48cb1d6 commit 8391b51

File tree

2 files changed

+19
-6
lines changed

2 files changed

+19
-6
lines changed

src/main/java/org/elasticsearch/common/joda/DateMathParser.java

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -78,12 +78,14 @@ public long parse(String text, Callable<Long> now, boolean roundCeil, DateTimeZo
7878
if (mathString.isEmpty()) {
7979
return time;
8080
}
81-
82-
return parseMath(mathString, time, roundCeil);
81+
return parseMath(mathString, time, roundCeil, timeZone);
8382
}
8483

85-
private long parseMath(String mathString, long time, boolean roundUp) throws ElasticsearchParseException {
86-
MutableDateTime dateTime = new MutableDateTime(time, DateTimeZone.UTC);
84+
private long parseMath(String mathString, long time, boolean roundUp, DateTimeZone timeZone) throws ElasticsearchParseException {
85+
if (timeZone == null) {
86+
timeZone = DateTimeZone.UTC;
87+
}
88+
MutableDateTime dateTime = new MutableDateTime(time, timeZone);
8789
for (int i = 0; i < mathString.length(); ) {
8890
char c = mathString.charAt(i++);
8991
final boolean round;

src/test/java/org/elasticsearch/common/joda/DateMathParserTests.java

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ void assertDateMathEquals(String toTest, String expected) {
4646

4747
void assertDateMathEquals(String toTest, String expected, long now, boolean roundUp, DateTimeZone timeZone) {
4848
DateMathParser parser = new DateMathParser(Joda.forPattern("dateOptionalTime"), TimeUnit.MILLISECONDS);
49-
long gotMillis = parser.parse(toTest, callable(now), roundUp, null);
49+
long gotMillis = parser.parse(toTest, callable(now), roundUp, timeZone);
5050
long expectedMillis = parser.parse(expected, callable(0));
5151
if (gotMillis != expectedMillis) {
5252
fail("Date math not equal\n" +
@@ -116,16 +116,27 @@ public void testRounding() {
116116
assertDateMathEquals("2014-11-18||/y", "2014-12-31T23:59:59.999", 0, true, null);
117117
assertDateMathEquals("2014||/y", "2014-01-01", 0, false, null);
118118
assertDateMathEquals("2014||/y", "2014-12-31T23:59:59.999", 0, true, null);
119+
assertDateMathEquals("2014-01-01T00:00:00.001||/y", "2014-12-31T23:59:59.999", 0, true, null);
120+
// rounding should also take into account time zone
121+
assertDateMathEquals("2014-11-18||/y", "2013-12-31T23:00:00.000Z", 0, false, DateTimeZone.forID("CET"));
122+
assertDateMathEquals("2014-11-18||/y", "2014-12-31T22:59:59.999Z", 0, true, DateTimeZone.forID("CET"));
119123

120124
assertDateMathEquals("2014-11-18||/M", "2014-11-01", 0, false, null);
121125
assertDateMathEquals("2014-11-18||/M", "2014-11-30T23:59:59.999", 0, true, null);
122126
assertDateMathEquals("2014-11||/M", "2014-11-01", 0, false, null);
123127
assertDateMathEquals("2014-11||/M", "2014-11-30T23:59:59.999", 0, true, null);
128+
assertDateMathEquals("2014-11-18||/M", "2014-10-31T23:00:00.000Z", 0, false, DateTimeZone.forID("CET"));
129+
assertDateMathEquals("2014-11-18||/M", "2014-11-30T22:59:59.999Z", 0, true, DateTimeZone.forID("CET"));
124130

125131
assertDateMathEquals("2014-11-18T14||/w", "2014-11-17", 0, false, null);
126132
assertDateMathEquals("2014-11-18T14||/w", "2014-11-23T23:59:59.999", 0, true, null);
127133
assertDateMathEquals("2014-11-18||/w", "2014-11-17", 0, false, null);
128134
assertDateMathEquals("2014-11-18||/w", "2014-11-23T23:59:59.999", 0, true, null);
135+
assertDateMathEquals("2014-11-18||/w", "2014-11-16T23:00:00.000Z", 0, false, DateTimeZone.forID("+01:00"));
136+
assertDateMathEquals("2014-11-18||/w", "2014-11-17T01:00:00.000Z", 0, false, DateTimeZone.forID("-01:00"));
137+
assertDateMathEquals("2014-11-18||/w", "2014-11-16T23:00:00.000Z", 0, false, DateTimeZone.forID("CET"));
138+
assertDateMathEquals("2014-11-18||/w", "2014-11-23T22:59:59.999Z", 0, true, DateTimeZone.forID("CET"));
139+
assertDateMathEquals("2014-07-22||/w", "2014-07-20T22:00:00.000Z", 0, false, DateTimeZone.forID("CET")); // with DST
129140

130141
assertDateMathEquals("2014-11-18T14||/d", "2014-11-18", 0, false, null);
131142
assertDateMathEquals("2014-11-18T14||/d", "2014-11-18T23:59:59.999", 0, true, null);
@@ -151,7 +162,7 @@ public void testRounding() {
151162
assertDateMathEquals("2014-11-18T14:27:32||/s", "2014-11-18T14:27:32", 0, false, null);
152163
assertDateMathEquals("2014-11-18T14:27:32||/s", "2014-11-18T14:27:32.999", 0, true, null);
153164
}
154-
165+
155166
void assertParseException(String msg, String date) {
156167
try {
157168
parser.parse(date, callable(0));

0 commit comments

Comments
 (0)