Polishing.
Introduce factory methods to convert TimeZone/ZoneId/ZoneOffset into Mongo Timezone. Introduce TemporalUnit abstraction and converters to convert ChronoUnit and TimeUnit into TemporalUnit for date operators accepting a unit parameter. See #3713 Original pull request: #3748.
This commit is contained in:
@@ -15,10 +15,16 @@
|
||||
*/
|
||||
package org.springframework.data.mongodb.core.aggregation;
|
||||
|
||||
import java.time.ZoneId;
|
||||
import java.time.ZoneOffset;
|
||||
import java.time.temporal.ChronoUnit;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.TimeZone;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
@@ -157,6 +163,7 @@ public class DateOperators {
|
||||
* <strong>NOTE: </strong>Support for timezones in aggregations Requires MongoDB 3.6 or later.
|
||||
*
|
||||
* @author Christoph Strobl
|
||||
* @author Mark Paluch
|
||||
* @since 2.1
|
||||
*/
|
||||
public static class Timezone {
|
||||
@@ -192,6 +199,61 @@ public class DateOperators {
|
||||
return new Timezone(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a {@link Timezone} for the given {@link TimeZone} rendering the offset as UTC offset.
|
||||
*
|
||||
* @param timeZone {@link TimeZone} rendering the offset as UTC offset.
|
||||
* @return new instance of {@link Timezone}.
|
||||
* @since 3.3
|
||||
*/
|
||||
public static Timezone fromOffset(TimeZone timeZone) {
|
||||
|
||||
Assert.notNull(timeZone, "TimeZone must not be null!");
|
||||
|
||||
return fromOffset(
|
||||
ZoneOffset.ofTotalSeconds(Math.toIntExact(TimeUnit.MILLISECONDS.toSeconds(timeZone.getRawOffset()))));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a {@link Timezone} for the given {@link ZoneOffset} rendering the offset as UTC offset.
|
||||
*
|
||||
* @param offset {@link ZoneOffset} rendering the offset as UTC offset.
|
||||
* @return new instance of {@link Timezone}.
|
||||
* @since 3.3
|
||||
*/
|
||||
public static Timezone fromOffset(ZoneOffset offset) {
|
||||
|
||||
Assert.notNull(offset, "ZoneOffset must not be null!");
|
||||
return new Timezone(offset.toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a {@link Timezone} for the given {@link TimeZone} rendering the offset as UTC offset.
|
||||
*
|
||||
* @param timeZone {@link Timezone} rendering the offset as zone identifier.
|
||||
* @return new instance of {@link Timezone}.
|
||||
* @since 3.3
|
||||
*/
|
||||
public static Timezone fromZone(TimeZone timeZone) {
|
||||
|
||||
Assert.notNull(timeZone, "TimeZone must not be null!");
|
||||
|
||||
return valueOf(timeZone.getID());
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a {@link Timezone} for the given {@link java.time.ZoneId} rendering the offset as UTC offset.
|
||||
*
|
||||
* @param zoneId {@link ZoneId} rendering the offset as zone identifier.
|
||||
* @return new instance of {@link Timezone}.
|
||||
* @since 3.3
|
||||
*/
|
||||
public static Timezone fromZone(ZoneId zoneId) {
|
||||
|
||||
Assert.notNull(zoneId, "ZoneId must not be null!");
|
||||
return new Timezone(zoneId.toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a {@link Timezone} for the {@link Field} reference holding the Olson Timezone Identifier or UTC Offset.
|
||||
*
|
||||
@@ -212,6 +274,11 @@ public class DateOperators {
|
||||
public static Timezone ofExpression(AggregationExpression expression) {
|
||||
return valueOf(expression);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
Object getValue() {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -303,32 +370,64 @@ public class DateOperators {
|
||||
|
||||
/**
|
||||
* Creates new {@link AggregationExpression} that adds the value of the given {@link AggregationExpression
|
||||
* expression} (in {@literal units). @param expression must not be {@literal null}.
|
||||
*
|
||||
* expression} (in {@literal units}).
|
||||
*
|
||||
* @param expression must not be {@literal null}.
|
||||
* @param unit the unit of measure. Must not be {@literal null}.
|
||||
* @return new instance of {@link DateAdd}.
|
||||
* @since 3.3
|
||||
* @return new instance of {@link DateAdd}. @since 3.3
|
||||
*/
|
||||
public DateAdd addValueOf(AggregationExpression expression, String unit) {
|
||||
return applyTimezone(DateAdd.addValueOf(expression, unit).toDate(dateReference()), timezone);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates new {@link AggregationExpression} that adds the value stored at the given {@literal field} (in
|
||||
* {@literal units). @param fieldReference must not be {@literal null}.
|
||||
*
|
||||
* Creates new {@link AggregationExpression} that adds the value of the given {@link AggregationExpression
|
||||
* expression} (in {@literal units}).
|
||||
*
|
||||
* @param expression must not be {@literal null}.
|
||||
* @param unit the unit of measure. Must not be {@literal null}.
|
||||
* @return new instance of {@link DateAdd}.
|
||||
* @since 3.3
|
||||
* @return new instance of {@link DateAdd}. @since 3.3
|
||||
*/
|
||||
public DateAdd addValueOf(AggregationExpression expression, TemporalUnit unit) {
|
||||
|
||||
Assert.notNull(unit, "TemporalUnit must not be null");
|
||||
return applyTimezone(DateAdd.addValueOf(expression, unit.name().toLowerCase(Locale.ROOT)).toDate(dateReference()),
|
||||
timezone);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates new {@link AggregationExpression} that adds the value stored at the given {@literal field} (in
|
||||
* {@literal units}).
|
||||
*
|
||||
* @param fieldReference must not be {@literal null}.
|
||||
* @param unit the unit of measure. Must not be {@literal null}.
|
||||
* @return new instance of {@link DateAdd}. @since 3.3
|
||||
*/
|
||||
public DateAdd addValueOf(String fieldReference, String unit) {
|
||||
return applyTimezone(DateAdd.addValueOf(fieldReference, unit).toDate(dateReference()), timezone);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates new {@link AggregationExpression} that adds the given value (in {@literal units). @param value must not
|
||||
* be {@literal null}. @param unit the unit of measure. Must not be {@literal null}.
|
||||
*
|
||||
* Creates new {@link AggregationExpression} that adds the value stored at the given {@literal field} (in
|
||||
* {@literal units}).
|
||||
*
|
||||
* @param fieldReference must not be {@literal null}.
|
||||
* @param unit the unit of measure. Must not be {@literal null}.
|
||||
* @return new instance of {@link DateAdd}. @since 3.3
|
||||
*/
|
||||
public DateAdd addValueOf(String fieldReference, TemporalUnit unit) {
|
||||
|
||||
Assert.notNull(unit, "TemporalUnit must not be null");
|
||||
|
||||
return applyTimezone(
|
||||
DateAdd.addValueOf(fieldReference, unit.name().toLowerCase(Locale.ROOT)).toDate(dateReference()), timezone);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates new {@link AggregationExpression} that adds the given value (in {@literal units}).
|
||||
*
|
||||
* @param value must not be {@literal null}.
|
||||
* @param unit the unit of measure. Must not be {@literal null}.
|
||||
* @return
|
||||
* @since 3.3 new instance of {@link DateAdd}.
|
||||
*/
|
||||
@@ -336,6 +435,22 @@ public class DateOperators {
|
||||
return applyTimezone(DateAdd.addValue(value, unit).toDate(dateReference()), timezone);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates new {@link AggregationExpression} that adds the given value (in {@literal units}).
|
||||
*
|
||||
* @param value must not be {@literal null}.
|
||||
* @param unit the unit of measure. Must not be {@literal null}.
|
||||
* @return
|
||||
* @since 3.3 new instance of {@link DateAdd}.
|
||||
*/
|
||||
public DateAdd add(Object value, TemporalUnit unit) {
|
||||
|
||||
Assert.notNull(unit, "TemporalUnit must not be null");
|
||||
|
||||
return applyTimezone(DateAdd.addValue(value, unit.name().toLowerCase(Locale.ROOT)).toDate(dateReference()),
|
||||
timezone);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates new {@link AggregationExpression} that returns the day of the year for a date as a number between 1 and
|
||||
* 366.
|
||||
@@ -367,41 +482,89 @@ public class DateOperators {
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates new {@link AggregationExpression} that calculates the difference (in {@literal units) to the date
|
||||
* computed by the given {@link AggregationExpression expression}. @param expression must not be {@literal null}.
|
||||
*
|
||||
* Creates new {@link AggregationExpression} that calculates the difference (in {@literal units}) to the date
|
||||
* computed by the given {@link AggregationExpression expression}.
|
||||
*
|
||||
* @param expression must not be {@literal null}.
|
||||
* @param unit the unit of measure. Must not be {@literal null}.
|
||||
* @return new instance of {@link DateAdd}.
|
||||
* @since 3.3
|
||||
* @return new instance of {@link DateAdd}. @since 3.3
|
||||
*/
|
||||
public DateDiff diffValueOf(AggregationExpression expression, String unit) {
|
||||
return applyTimezone(DateDiff.diffValueOf(expression, unit).toDate(dateReference()), timezone);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates new {@link AggregationExpression} that calculates the difference (in {@literal units) to the date stored
|
||||
* at the given {@literal field}. @param expression must not be {@literal null}.
|
||||
*
|
||||
* Creates new {@link AggregationExpression} that calculates the difference (in {@literal units}) to the date
|
||||
* computed by the given {@link AggregationExpression expression}.
|
||||
*
|
||||
* @param expression must not be {@literal null}.
|
||||
* @param unit the unit of measure. Must not be {@literal null}.
|
||||
* @return new instance of {@link DateAdd}.
|
||||
* @since 3.3
|
||||
* @return new instance of {@link DateAdd}. @since 3.3
|
||||
*/
|
||||
public DateDiff diffValueOf(AggregationExpression expression, TemporalUnit unit) {
|
||||
|
||||
Assert.notNull(unit, "TemporalUnit must not be null");
|
||||
|
||||
return applyTimezone(
|
||||
DateDiff.diffValueOf(expression, unit.name().toLowerCase(Locale.ROOT)).toDate(dateReference()), timezone);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates new {@link AggregationExpression} that calculates the difference (in {@literal units}) to the date stored
|
||||
* at the given {@literal field}.
|
||||
*
|
||||
* @param fieldReference must not be {@literal null}.
|
||||
* @param unit the unit of measure. Must not be {@literal null}.
|
||||
* @return new instance of {@link DateAdd}. @since 3.3
|
||||
*/
|
||||
public DateDiff diffValueOf(String fieldReference, String unit) {
|
||||
return applyTimezone(DateDiff.diffValueOf(fieldReference, unit).toDate(dateReference()), timezone);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates new {@link AggregationExpression} that calculates the difference (in {@literal units) to the date given
|
||||
* {@literal value}. @param value anything the resolves to a valid date. Must not be {@literal null}.
|
||||
*
|
||||
* Creates new {@link AggregationExpression} that calculates the difference (in {@literal units}) to the date stored
|
||||
* at the given {@literal field}.
|
||||
*
|
||||
* @param fieldReference must not be {@literal null}.
|
||||
* @param unit the unit of measure. Must not be {@literal null}.
|
||||
* @return new instance of {@link DateAdd}.
|
||||
* @since 3.3
|
||||
* @return new instance of {@link DateAdd}. @since 3.3
|
||||
*/
|
||||
public DateDiff diffValueOf(String fieldReference, TemporalUnit unit) {
|
||||
|
||||
Assert.notNull(unit, "TemporalUnit must not be null");
|
||||
|
||||
return applyTimezone(
|
||||
DateDiff.diffValueOf(fieldReference, unit.name().toLowerCase(Locale.ROOT)).toDate(dateReference()), timezone);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates new {@link AggregationExpression} that calculates the difference (in {@literal units}) to the date given
|
||||
* {@literal value}.
|
||||
*
|
||||
* @param value anything the resolves to a valid date. Must not be {@literal null}.
|
||||
* @param unit the unit of measure. Must not be {@literal null}.
|
||||
* @return new instance of {@link DateAdd}. @since 3.3
|
||||
*/
|
||||
public DateDiff diff(Object value, String unit) {
|
||||
return applyTimezone(DateDiff.diffValue(value, unit).toDate(dateReference()), timezone);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates new {@link AggregationExpression} that calculates the difference (in {@literal units}) to the date given
|
||||
* {@literal value}.
|
||||
*
|
||||
* @param value anything the resolves to a valid date. Must not be {@literal null}.
|
||||
* @param unit the unit of measure. Must not be {@literal null}.
|
||||
* @return new instance of {@link DateAdd}. @since 3.3
|
||||
*/
|
||||
public DateDiff diff(Object value, TemporalUnit unit) {
|
||||
|
||||
Assert.notNull(unit, "TemporalUnit must not be null");
|
||||
|
||||
return applyTimezone(DateDiff.diffValue(value, unit.name().toLowerCase(Locale.ROOT)).toDate(dateReference()),
|
||||
timezone);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates new {@link AggregationExpression} that returns the year portion of a date.
|
||||
*
|
||||
@@ -2720,6 +2883,85 @@ public class DateOperators {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Interface defining a temporal unit for date operators.
|
||||
*
|
||||
* @author Mark Paluch
|
||||
* @since 3.3
|
||||
*/
|
||||
public interface TemporalUnit {
|
||||
|
||||
String name();
|
||||
|
||||
/**
|
||||
* Converts the given time unit into a {@link TemporalUnit}. Supported units are: days, hours, minutes, seconds, and
|
||||
* milliseconds.
|
||||
*
|
||||
* @param timeUnit the time unit to convert, must not be {@literal null}.
|
||||
* @return
|
||||
* @throws IllegalArgumentException if the {@link TimeUnit} is {@literal null} or not supported for conversion.
|
||||
*/
|
||||
static TemporalUnit from(TimeUnit timeUnit) {
|
||||
|
||||
Assert.notNull(timeUnit, "TimeUnit must not be null");
|
||||
|
||||
switch (timeUnit) {
|
||||
case DAYS:
|
||||
return TemporalUnits.DAY;
|
||||
case HOURS:
|
||||
return TemporalUnits.HOUR;
|
||||
case MINUTES:
|
||||
return TemporalUnits.MINUTE;
|
||||
case SECONDS:
|
||||
return TemporalUnits.SECOND;
|
||||
case MILLISECONDS:
|
||||
return TemporalUnits.MILLISECOND;
|
||||
}
|
||||
|
||||
throw new IllegalArgumentException(String.format("Cannot create TemporalUnit from %s", timeUnit));
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the given chrono unit into a {@link TemporalUnit}. Supported units are: years, weeks, months, days,
|
||||
* hours, minutes, seconds, and millis.
|
||||
*
|
||||
* @param chronoUnit the chrono unit to convert, must not be {@literal null}.
|
||||
* @return
|
||||
* @throws IllegalArgumentException if the {@link TimeUnit} is {@literal null} or not supported for conversion.
|
||||
*/
|
||||
static TemporalUnit from(ChronoUnit chronoUnit) {
|
||||
|
||||
switch (chronoUnit) {
|
||||
case YEARS:
|
||||
return TemporalUnits.YEAR;
|
||||
case WEEKS:
|
||||
return TemporalUnits.WEEK;
|
||||
case MONTHS:
|
||||
return TemporalUnits.MONTH;
|
||||
case DAYS:
|
||||
return TemporalUnits.DAY;
|
||||
case HOURS:
|
||||
return TemporalUnits.HOUR;
|
||||
case MINUTES:
|
||||
return TemporalUnits.MINUTE;
|
||||
case SECONDS:
|
||||
return TemporalUnits.SECOND;
|
||||
case MILLIS:
|
||||
return TemporalUnits.MILLISECOND;
|
||||
}
|
||||
|
||||
throw new IllegalArgumentException(String.format("Cannot create TemporalUnit from %s", chronoUnit));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Supported temporal units.
|
||||
*/
|
||||
enum TemporalUnits implements TemporalUnit {
|
||||
YEAR, QUARTER, WEEK, MONTH, DAY, HOUR, MINUTE, SECOND, MILLISECOND
|
||||
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private static <T extends TimezonedDateAggregationExpression> T applyTimezone(T instance, Timezone timezone) {
|
||||
return !ObjectUtils.nullSafeEquals(Timezone.none(), timezone) && !instance.hasTimezone()
|
||||
|
||||
@@ -15,9 +15,11 @@
|
||||
*/
|
||||
package org.springframework.data.mongodb.core.aggregation;
|
||||
|
||||
import java.time.temporal.ChronoUnit;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.bson.Document;
|
||||
import org.springframework.data.domain.Sort;
|
||||
@@ -626,7 +628,68 @@ public class SetWindowFieldsOperation
|
||||
* The actual time unit to apply to a {@link Window}.
|
||||
*/
|
||||
public interface WindowUnit {
|
||||
|
||||
String name();
|
||||
|
||||
/**
|
||||
* Converts the given time unit into a {@link WindowUnit}. Supported units are: days, hours, minutes, seconds, and
|
||||
* milliseconds.
|
||||
*
|
||||
* @param timeUnit the time unit to convert, must not be {@literal null}.
|
||||
* @return
|
||||
* @throws IllegalArgumentException if the {@link TimeUnit} is {@literal null} or not supported for conversion.
|
||||
*/
|
||||
static WindowUnit from(TimeUnit timeUnit) {
|
||||
|
||||
Assert.notNull(timeUnit, "TimeUnit must not be null");
|
||||
|
||||
switch (timeUnit) {
|
||||
case DAYS:
|
||||
return WindowUnits.DAY;
|
||||
case HOURS:
|
||||
return WindowUnits.HOUR;
|
||||
case MINUTES:
|
||||
return WindowUnits.MINUTE;
|
||||
case SECONDS:
|
||||
return WindowUnits.SECOND;
|
||||
case MILLISECONDS:
|
||||
return WindowUnits.MILLISECOND;
|
||||
}
|
||||
|
||||
throw new IllegalArgumentException(String.format("Cannot create WindowUnit from %s", timeUnit));
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the given chrono unit into a {@link WindowUnit}. Supported units are: years, weeks, months, days, hours,
|
||||
* minutes, seconds, and millis.
|
||||
*
|
||||
* @param chronoUnit the chrono unit to convert, must not be {@literal null}.
|
||||
* @return
|
||||
* @throws IllegalArgumentException if the {@link TimeUnit} is {@literal null} or not supported for conversion.
|
||||
*/
|
||||
static WindowUnit from(ChronoUnit chronoUnit) {
|
||||
|
||||
switch (chronoUnit) {
|
||||
case YEARS:
|
||||
return WindowUnits.YEAR;
|
||||
case WEEKS:
|
||||
return WindowUnits.WEEK;
|
||||
case MONTHS:
|
||||
return WindowUnits.MONTH;
|
||||
case DAYS:
|
||||
return WindowUnits.DAY;
|
||||
case HOURS:
|
||||
return WindowUnits.HOUR;
|
||||
case MINUTES:
|
||||
return WindowUnits.MINUTE;
|
||||
case SECONDS:
|
||||
return WindowUnits.SECOND;
|
||||
case MILLIS:
|
||||
return WindowUnits.MILLISECOND;
|
||||
}
|
||||
|
||||
throw new IllegalArgumentException(String.format("Cannot create WindowUnit from %s", chronoUnit));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -15,14 +15,22 @@
|
||||
*/
|
||||
package org.springframework.data.mongodb.core.aggregation;
|
||||
|
||||
import static org.assertj.core.api.Assertions.*;
|
||||
import static org.springframework.data.mongodb.test.util.Assertions.*;
|
||||
|
||||
import java.time.ZoneId;
|
||||
import java.time.ZoneOffset;
|
||||
import java.time.temporal.ChronoUnit;
|
||||
import java.util.TimeZone;
|
||||
|
||||
import org.bson.Document;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.data.mongodb.core.aggregation.DateOperators.Timezone;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link DateOperators}.
|
||||
*
|
||||
* @author Christoph Strobl
|
||||
* @author Mark Paluch
|
||||
*/
|
||||
class DateOperatorsUnitTests {
|
||||
|
||||
@@ -30,15 +38,15 @@ class DateOperatorsUnitTests {
|
||||
void rendersDateAdd() {
|
||||
|
||||
assertThat(DateOperators.dateOf("purchaseDate").add(3, "day").toDocument(Aggregation.DEFAULT_CONTEXT))
|
||||
.isEqualTo(Document.parse("{ $dateAdd: { startDate: \"$purchaseDate\", unit: \"day\", amount: 3 } }"));
|
||||
.isEqualTo("{ $dateAdd: { startDate: \"$purchaseDate\", unit: \"day\", amount: 3 } }");
|
||||
}
|
||||
|
||||
@Test // GH-3713
|
||||
void rendersDateAddWithTimezone() {
|
||||
|
||||
assertThat(DateOperators.zonedDateOf("purchaseDate", Timezone.valueOf("America/Chicago")).add(3, "day")
|
||||
.toDocument(Aggregation.DEFAULT_CONTEXT)).isEqualTo(Document.parse(
|
||||
"{ $dateAdd: { startDate: \"$purchaseDate\", unit: \"day\", amount: 3, timezone : \"America/Chicago\" } }"));
|
||||
.toDocument(Aggregation.DEFAULT_CONTEXT)).isEqualTo(
|
||||
"{ $dateAdd: { startDate: \"$purchaseDate\", unit: \"day\", amount: 3, timezone : \"America/Chicago\" } }");
|
||||
}
|
||||
|
||||
@Test // GH-3713
|
||||
@@ -46,15 +54,37 @@ class DateOperatorsUnitTests {
|
||||
|
||||
assertThat(
|
||||
DateOperators.dateOf("purchaseDate").diffValueOf("delivered", "day").toDocument(Aggregation.DEFAULT_CONTEXT))
|
||||
.isEqualTo(Document
|
||||
.parse("{ $dateDiff: { startDate: \"$purchaseDate\", endDate: \"$delivered\", unit: \"day\" } }"));
|
||||
.isEqualTo("{ $dateDiff: { startDate: \"$purchaseDate\", endDate: \"$delivered\", unit: \"day\" } }");
|
||||
}
|
||||
|
||||
@Test // GH-3713
|
||||
void rendersDateDiffWithTimezone() {
|
||||
|
||||
assertThat(DateOperators.zonedDateOf("purchaseDate", Timezone.valueOf("America/Chicago"))
|
||||
.diffValueOf("delivered", "day").toDocument(Aggregation.DEFAULT_CONTEXT)).isEqualTo(Document.parse(
|
||||
"{ $dateDiff: { startDate: \"$purchaseDate\", endDate: \"$delivered\", unit: \"day\", timezone : \"America/Chicago\" } }"));
|
||||
.diffValueOf("delivered", DateOperators.TemporalUnit.from(ChronoUnit.DAYS))
|
||||
.toDocument(Aggregation.DEFAULT_CONTEXT)).isEqualTo(
|
||||
"{ $dateDiff: { startDate: \"$purchaseDate\", endDate: \"$delivered\", unit: \"day\", timezone : \"America/Chicago\" } }");
|
||||
}
|
||||
|
||||
@Test // GH-3713
|
||||
void rendersTimezoneFromZoneOffset() {
|
||||
assertThat(DateOperators.Timezone.fromOffset(ZoneOffset.ofHoursMinutes(3, 30)).getValue()).isEqualTo("+03:30");
|
||||
}
|
||||
|
||||
@Test // GH-3713
|
||||
void rendersTimezoneFromTimeZoneOffset() {
|
||||
assertThat(DateOperators.Timezone.fromOffset(TimeZone.getTimeZone("America/Chicago")).getValue())
|
||||
.isEqualTo("-06:00");
|
||||
}
|
||||
|
||||
@Test // GH-3713
|
||||
void rendersTimezoneFromTimeZoneId() {
|
||||
assertThat(DateOperators.Timezone.fromZone(TimeZone.getTimeZone("America/Chicago")).getValue())
|
||||
.isEqualTo("America/Chicago");
|
||||
}
|
||||
|
||||
@Test // GH-3713
|
||||
void rendersTimezoneFromZoneId() {
|
||||
assertThat(DateOperators.Timezone.fromZone(ZoneId.of("America/Chicago")).getValue()).isEqualTo("America/Chicago");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1034,11 +1034,6 @@ public class SpelExpressionTransformerUnitTests {
|
||||
assertThat(transform("tanh(angle)")).isEqualTo("{ \"$tanh\" : \"$angle\"}");
|
||||
}
|
||||
|
||||
private Document transform(String expression, Object... params) {
|
||||
return (Document) transformer.transform(expression, Aggregation.DEFAULT_CONTEXT, params);
|
||||
}
|
||||
|
||||
private Object transformValue(String expression, Object... params) {
|
||||
@Test // GH-3713
|
||||
void shouldRenderDateAdd() {
|
||||
assertThat(transform("dateAdd(purchaseDate, 'day', 3)")).isEqualTo(Document.parse("{ $dateAdd: { startDate: \"$purchaseDate\", unit: \"day\", amount: 3 } }"));
|
||||
@@ -1049,7 +1044,11 @@ public class SpelExpressionTransformerUnitTests {
|
||||
assertThat(transform("dateDiff(purchaseDate, delivered, 'day')")).isEqualTo(Document.parse("{ $dateDiff: { startDate: \"$purchaseDate\", endDate: \"$delivered\", unit: \"day\" } }"));
|
||||
}
|
||||
|
||||
private Object transform(String expression, Object... params) {
|
||||
private Document transform(String expression, Object... params) {
|
||||
return (Document) transformer.transform(expression, Aggregation.DEFAULT_CONTEXT, params);
|
||||
}
|
||||
|
||||
private Object transformValue(String expression, Object... params) {
|
||||
Object result = transformer.transform(expression, Aggregation.DEFAULT_CONTEXT, params);
|
||||
return result == null ? null : (!(result instanceof org.bson.Document) ? result.toString() : result);
|
||||
}
|
||||
|
||||
@@ -100,7 +100,7 @@ At the time of this writing, we provide support for the following Aggregation Op
|
||||
| `literal`
|
||||
|
||||
| Date Aggregation Operators
|
||||
| `dayOfYear`, `dayOfMonth`, `dayOfWeek`, `year`, `month`, `week`, `hour`, `minute`, `second`, `millisecond`, `dateToString`, `dateFromString`, `dateFromParts`, `dateToParts`, `isoDayOfWeek`, `isoWeek`, `isoWeekYear`
|
||||
| `dayOfYear`, `dayOfMonth`, `dayOfWeek`, `year`, `month`, `week`, `hour`, `minute`, `second`, `millisecond`, `dateAdd`, `dateDiff`, `dateToString`, `dateFromString`, `dateFromParts`, `dateToParts`, `isoDayOfWeek`, `isoWeek`, `isoWeekYear`
|
||||
|
||||
| Variable Operators
|
||||
| `map`
|
||||
|
||||
Reference in New Issue
Block a user