Skip to content

Commit 8b69f18

Browse files
committed
Implement date expressions (#1045)
JAVA-4804
1 parent 7ac3ccd commit 8b69f18

File tree

4 files changed

+241
-2
lines changed

4 files changed

+241
-2
lines changed

driver-core/src/main/com/mongodb/client/model/expressions/DateExpression.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,5 +20,18 @@
2020
* Expresses a date value.
2121
*/
2222
public interface DateExpression extends Expression {
23+
IntegerExpression year(StringExpression timezone);
24+
IntegerExpression month(StringExpression timezone);
25+
IntegerExpression dayOfMonth(StringExpression timezone);
26+
IntegerExpression dayOfWeek(StringExpression timezone);
27+
IntegerExpression dayOfYear(StringExpression timezone);
28+
IntegerExpression hour(StringExpression timezone);
29+
IntegerExpression minute(StringExpression timezone);
30+
IntegerExpression second(StringExpression timezone);
31+
IntegerExpression week(StringExpression timezone);
32+
IntegerExpression millisecond(StringExpression timezone);
33+
34+
StringExpression dateToString();
35+
StringExpression dateToString(StringExpression timezone, StringExpression format);
2336

2437
}

driver-core/src/main/com/mongodb/client/model/expressions/Expressions.java

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,7 @@
3333

3434
import java.time.Instant;
3535
import java.util.ArrayList;
36-
import java.util.Arrays;
3736
import java.util.List;
38-
import java.util.stream.Collectors;
3937

4038
import static com.mongodb.client.model.expressions.MqlExpression.AstPlaceholder;
4139

driver-core/src/main/com/mongodb/client/model/expressions/MqlExpression.java

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -332,6 +332,77 @@ public IntegerExpression min(final IntegerExpression i) {
332332
return new MqlExpression<>(ast("$min", i));
333333
}
334334

335+
/** @see DateExpression */
336+
337+
private MqlExpression<Expression> usingTimezone(final String name, final StringExpression timezone) {
338+
return new MqlExpression<>((cr) -> astDoc(name, new BsonDocument()
339+
.append("date", this.toBsonValue(cr))
340+
.append("timezone", extractBsonValue(cr, timezone))));
341+
}
342+
343+
@Override
344+
public IntegerExpression year(final StringExpression timezone) {
345+
return usingTimezone("$year", timezone);
346+
}
347+
348+
@Override
349+
public IntegerExpression month(final StringExpression timezone) {
350+
return usingTimezone("$month", timezone);
351+
}
352+
353+
@Override
354+
public IntegerExpression dayOfMonth(final StringExpression timezone) {
355+
return usingTimezone("$dayOfMonth", timezone);
356+
}
357+
358+
@Override
359+
public IntegerExpression dayOfWeek(final StringExpression timezone) {
360+
return usingTimezone("$dayOfWeek", timezone);
361+
}
362+
363+
@Override
364+
public IntegerExpression dayOfYear(final StringExpression timezone) {
365+
return usingTimezone("$dayOfYear", timezone);
366+
}
367+
368+
@Override
369+
public IntegerExpression hour(final StringExpression timezone) {
370+
return usingTimezone("$hour", timezone);
371+
}
372+
373+
@Override
374+
public IntegerExpression minute(final StringExpression timezone) {
375+
return usingTimezone("$minute", timezone);
376+
}
377+
378+
@Override
379+
public IntegerExpression second(final StringExpression timezone) {
380+
return usingTimezone("$second", timezone);
381+
}
382+
383+
@Override
384+
public IntegerExpression week(final StringExpression timezone) {
385+
return usingTimezone("$week", timezone);
386+
}
387+
388+
@Override
389+
public IntegerExpression millisecond(final StringExpression timezone) {
390+
return usingTimezone("$millisecond", timezone);
391+
}
392+
393+
@Override
394+
public StringExpression dateToString() {
395+
return newMqlExpression((cr) -> astDoc("$dateToString", new BsonDocument()
396+
.append("date", this.toBsonValue(cr))));
397+
}
398+
399+
@Override
400+
public StringExpression dateToString(final StringExpression timezone, final StringExpression format) {
401+
return newMqlExpression((cr) -> astDoc("$dateToString", new BsonDocument()
402+
.append("date", this.toBsonValue(cr))
403+
.append("format", extractBsonValue(cr, format))
404+
.append("timezone", extractBsonValue(cr, timezone))));
405+
}
335406

336407
/** @see StringExpression */
337408

Lines changed: 157 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,157 @@
1+
/*
2+
* Copyright 2008-present MongoDB, Inc.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.mongodb.client.model.expressions;
18+
19+
import org.junit.jupiter.api.Test;
20+
21+
import java.time.Instant;
22+
import java.time.ZoneId;
23+
import java.time.ZoneOffset;
24+
import java.time.ZonedDateTime;
25+
import java.time.temporal.ChronoField;
26+
27+
import static com.mongodb.client.model.expressions.Expressions.of;
28+
import static java.time.format.DateTimeFormatter.ISO_LOCAL_DATE_TIME;
29+
30+
class DateExpressionsFunctionalTest extends AbstractExpressionsFunctionalTest {
31+
// https://www.mongodb.com/docs/manual/reference/operator/aggregation/#date-expression-operators
32+
33+
private final Instant instant = Instant.parse("2007-12-03T10:15:30.005Z");
34+
private final DateExpression date = of(instant);
35+
private final ZonedDateTime utcDateTime = ZonedDateTime.ofInstant(instant, ZoneId.of(ZoneOffset.UTC.getId()));
36+
private final StringExpression utc = of("UTC");
37+
38+
@Test
39+
public void literalsTest() {
40+
assertExpression(
41+
instant,
42+
date,
43+
"{'$date': '2007-12-03T10:15:30.005Z'}");
44+
}
45+
46+
@Test
47+
public void yearTest() {
48+
// https://www.mongodb.com/docs/manual/reference/operator/aggregation/year/
49+
assertExpression(
50+
utcDateTime.get(ChronoField.YEAR),
51+
date.year(utc),
52+
"{'$year': {'date': {'$date': '2007-12-03T10:15:30.005Z'}, 'timezone': 'UTC'}}");
53+
}
54+
55+
@Test
56+
public void monthTest() {
57+
// https://www.mongodb.com/docs/manual/reference/operator/aggregation/month/
58+
assertExpression(
59+
utcDateTime.get(ChronoField.MONTH_OF_YEAR),
60+
date.month(utc),
61+
"{'$month': {'date': {'$date': '2007-12-03T10:15:30.005Z'}, 'timezone': 'UTC'}}");
62+
}
63+
64+
@Test
65+
public void dayOfMonthTest() {
66+
// https://www.mongodb.com/docs/manual/reference/operator/aggregation/dayOfMonth/
67+
assertExpression(
68+
utcDateTime.get(ChronoField.DAY_OF_MONTH),
69+
date.dayOfMonth(utc),
70+
"{'$dayOfMonth': {'date': {'$date': '2007-12-03T10:15:30.005Z'}, 'timezone': 'UTC'}}");
71+
}
72+
73+
@Test
74+
public void dayOfWeekTest() {
75+
// https://www.mongodb.com/docs/manual/reference/operator/aggregation/dayOfWeek/
76+
assertExpression(
77+
utcDateTime.get(ChronoField.DAY_OF_WEEK) + 1,
78+
date.dayOfWeek(utc),
79+
"{'$dayOfWeek': {'date': {'$date': '2007-12-03T10:15:30.005Z'}, 'timezone': 'UTC'}}");
80+
}
81+
82+
@Test
83+
public void dayOfYearTest() {
84+
// https://www.mongodb.com/docs/manual/reference/operator/aggregation/dayOfYear/
85+
assertExpression(
86+
utcDateTime.get(ChronoField.DAY_OF_YEAR),
87+
date.dayOfYear(utc),
88+
"{'$dayOfYear': {'date': {'$date': '2007-12-03T10:15:30.005Z'}, 'timezone': 'UTC'}}");
89+
}
90+
91+
@Test
92+
public void hourTest() {
93+
// https://www.mongodb.com/docs/manual/reference/operator/aggregation/hour/
94+
assertExpression(
95+
utcDateTime.get(ChronoField.HOUR_OF_DAY),
96+
date.hour(utc),
97+
"{'$hour': {'date': {'$date': '2007-12-03T10:15:30.005Z'}, 'timezone': 'UTC'}}");
98+
}
99+
100+
@Test
101+
public void minuteTest() {
102+
// https://www.mongodb.com/docs/manual/reference/operator/aggregation/minute/
103+
assertExpression(
104+
utcDateTime.get(ChronoField.MINUTE_OF_HOUR),
105+
date.minute(utc),
106+
"{'$minute': {'date': {'$date': '2007-12-03T10:15:30.005Z'}, 'timezone': 'UTC'}}");
107+
}
108+
109+
@Test
110+
public void secondTest() {
111+
// https://www.mongodb.com/docs/manual/reference/operator/aggregation/second/
112+
assertExpression(
113+
utcDateTime.get(ChronoField.SECOND_OF_MINUTE),
114+
date.second(utc),
115+
"{'$second': {'date': {'$date': '2007-12-03T10:15:30.005Z'}, 'timezone': 'UTC'}}");
116+
}
117+
118+
@Test
119+
public void weekTest() {
120+
// https://www.mongodb.com/docs/manual/reference/operator/aggregation/week/
121+
assertExpression(
122+
48,
123+
date.week(utc),
124+
"{'$week': {'date': {'$date': '2007-12-03T10:15:30.005Z'}, 'timezone': 'UTC'}}");
125+
}
126+
127+
@Test
128+
public void millisecondTest() {
129+
// https://www.mongodb.com/docs/manual/reference/operator/aggregation/millisecond/
130+
assertExpression(
131+
utcDateTime.get(ChronoField.MILLI_OF_SECOND),
132+
date.millisecond(utc),
133+
"{'$millisecond': {'date': {'$date': '2007-12-03T10:15:30.005Z'}, 'timezone': 'UTC'}}");
134+
}
135+
136+
@Test
137+
public void dateToStringTest() {
138+
// https://www.mongodb.com/docs/manual/reference/operator/aggregation/dateToString/
139+
assertExpression(
140+
instant.toString(),
141+
date.dateToString(),
142+
"{'$dateToString': {'date': {'$date': '2007-12-03T10:15:30.005Z'}}}");
143+
// with parameters
144+
assertExpression(
145+
utcDateTime.withZoneSameInstant(ZoneId.of("America/New_York")).format(ISO_LOCAL_DATE_TIME),
146+
date.dateToString(of("America/New_York"), of("%Y-%m-%dT%H:%M:%S.%L")),
147+
"{'$dateToString': {'date': {'$date': '2007-12-03T10:15:30.005Z'}, "
148+
+ "'format': '%Y-%m-%dT%H:%M:%S.%L', "
149+
+ "'timezone': 'America/New_York'}}");
150+
assertExpression(
151+
utcDateTime.withZoneSameInstant(ZoneId.of("+04:30")).format(ISO_LOCAL_DATE_TIME),
152+
date.dateToString(of("+04:30"), of("%Y-%m-%dT%H:%M:%S.%L")),
153+
"{'$dateToString': {'date': {'$date': '2007-12-03T10:15:30.005Z'}, "
154+
+ "'format': '%Y-%m-%dT%H:%M:%S.%L', "
155+
+ "'timezone': '+04:30'}}");
156+
}
157+
}

0 commit comments

Comments
 (0)