diff --git a/activitytype-cql/src/main/java/io/nosqlbench/activitytype/cql/datamappers/functions/to_daterange/DateRangeDuring.java b/activitytype-cql/src/main/java/io/nosqlbench/activitytype/cql/datamappers/functions/to_daterange/DateRangeDuring.java
new file mode 100644
index 000000000..cb7218c2f
--- /dev/null
+++ b/activitytype-cql/src/main/java/io/nosqlbench/activitytype/cql/datamappers/functions/to_daterange/DateRangeDuring.java
@@ -0,0 +1,46 @@
+package io.nosqlbench.activitytype.cql.datamappers.functions.to_daterange;
+
+import com.datastax.driver.dse.search.DateRange;
+import io.nosqlbench.virtdata.annotations.Example;
+import io.nosqlbench.virtdata.annotations.ThreadSafeMapper;
+
+import java.util.Date;
+import java.util.function.Function;
+import java.util.function.LongFunction;
+
+/**
+ * Takes an input as a reference point in epoch time, and converts it to a DateRange,
+ * with the bounds set to the lower and upper timestamps which align to the
+ * specified precision. You can use any of these precisions to control the bounds
+ * around the provided timestamp:
+ *
+ * - millisecond
+ * - second
+ * - minute
+ * - hour
+ * - day
+ * - month
+ * - year
+ *
+ */
+@ThreadSafeMapper
+public class DateRangeDuring implements LongFunction {
+
+ private final com.datastax.driver.dse.search.DateRange.DateRangeBound.Precision precision;
+
+ @Example({"DateRangeDuring('millisecond')}","Convert the incoming millisecond to an equivalent DateRange"})
+ @Example({"DateRangeDuring('minute')}","Convert the incoming millisecond to a DateRange for the minute in which the " +
+ "millisecond falls"})
+ public DateRangeDuring(String precision) {
+ this.precision = com.datastax.driver.dse.search.DateRange.DateRangeBound.Precision.valueOf(precision.toUpperCase());
+ }
+
+ @Override
+ public DateRange apply(long value) {
+ Date date = new Date(value);
+ com.datastax.driver.dse.search.DateRange.DateRangeBound lower = com.datastax.driver.dse.search.DateRange.DateRangeBound.lowerBound(date, precision);
+ com.datastax.driver.dse.search.DateRange.DateRangeBound upper = com.datastax.driver.dse.search.DateRange.DateRangeBound.upperBound(date, precision);
+ com.datastax.driver.dse.search.DateRange dateRange = new com.datastax.driver.dse.search.DateRange(lower, upper);
+ return dateRange;
+ }
+}
diff --git a/activitytype-cql/src/main/java/io/nosqlbench/activitytype/cql/datamappers/functions/to_daterange/DateRangeFunc.java b/activitytype-cql/src/main/java/io/nosqlbench/activitytype/cql/datamappers/functions/to_daterange/DateRangeFunc.java
new file mode 100644
index 000000000..1ee771640
--- /dev/null
+++ b/activitytype-cql/src/main/java/io/nosqlbench/activitytype/cql/datamappers/functions/to_daterange/DateRangeFunc.java
@@ -0,0 +1,60 @@
+package io.nosqlbench.activitytype.cql.datamappers.functions.to_daterange;
+
+import com.datastax.driver.dse.search.DateRange;
+import io.nosqlbench.virtdata.annotations.Example;
+import io.nosqlbench.virtdata.annotations.ThreadSafeMapper;
+
+import java.util.Date;
+import java.util.function.Function;
+import java.util.function.LongFunction;
+import java.util.function.LongUnaryOperator;
+
+/**
+ * Uses the precision and the two functions provided to create a DateRange.
+ * You can use any of these precisions to control the bounds
+ * around the provided timestamp:
+ *
+ * - millisecond
+ * - second
+ * - minute
+ * - hour
+ * - day
+ * - month
+ * - year
+ *
+ */
+@ThreadSafeMapper
+public class DateRangeFunc implements LongFunction {
+
+ private final DateRange.DateRangeBound.Precision precision;
+ private final LongUnaryOperator lower;
+ private final LongUnaryOperator upper;
+
+ public DateRangeFunc(String precision, LongUnaryOperator lower, LongUnaryOperator upper) {
+ this.precision = DateRange.DateRangeBound.Precision.valueOf(precision.toUpperCase());
+ this.lower = lower;
+ this.upper = upper;
+ }
+ public DateRangeFunc(String precision, LongFunction lower, LongFunction upper) {
+ this.precision = DateRange.DateRangeBound.Precision.valueOf(precision.toUpperCase());
+ this.lower = lower::apply;
+ this.upper = upper::apply;
+ }
+ public DateRangeFunc(String precision, Function lower, Function upper) {
+ this.precision = DateRange.DateRangeBound.Precision.valueOf(precision.toUpperCase());
+ this.lower = lower::apply;
+ this.upper = upper::apply;
+ }
+
+
+
+ @Override
+ public DateRange apply(long value) {
+ Date lowerDate = new Date(lower.applyAsLong(value));
+ DateRange.DateRangeBound lower = DateRange.DateRangeBound.lowerBound(lowerDate,precision);
+ Date upperDate = new Date(upper.applyAsLong(value));
+ DateRange.DateRangeBound upper = DateRange.DateRangeBound.upperBound(lowerDate,precision);
+ DateRange dateRange = new DateRange(lower, upper);
+ return dateRange;
+ }
+}
diff --git a/activitytype-cql/src/main/java/io/nosqlbench/activitytype/cql/datamappers/functions/to_daterange/DateRangeOnOrAfter.java b/activitytype-cql/src/main/java/io/nosqlbench/activitytype/cql/datamappers/functions/to_daterange/DateRangeOnOrAfter.java
new file mode 100644
index 000000000..bb0cfe922
--- /dev/null
+++ b/activitytype-cql/src/main/java/io/nosqlbench/activitytype/cql/datamappers/functions/to_daterange/DateRangeOnOrAfter.java
@@ -0,0 +1,48 @@
+package io.nosqlbench.activitytype.cql.datamappers.functions.to_daterange;
+
+import com.datastax.driver.dse.search.DateRange;
+import io.nosqlbench.virtdata.annotations.Example;
+import io.nosqlbench.virtdata.annotations.ThreadSafeMapper;
+
+import java.util.Date;
+import java.util.function.Function;
+import java.util.function.LongFunction;
+
+/**
+ * Takes an input as a reference point in epoch time, and converts it to a DateRange,
+ * with the lower bounds set to the lower bound of the precision and millisecond
+ * provided, and with no upper bound.
+ * You can use any of these precisions to control the bounds
+ * around the provided timestamp:
+ *
+ * - millisecond
+ * - second
+ * - minute
+ * - hour
+ * - day
+ * - month
+ * - year
+ *
+ */
+@ThreadSafeMapper
+public class DateRangeOnOrAfter implements LongFunction {
+
+ private final DateRange.DateRangeBound.Precision precision;
+
+ @Example({"DateRangeOnOrAfter('millisecond')}","Convert the incoming millisecond to an match any time on or after"})
+ @Example({"DateRangeOnOrAfter('minute')}","Convert the incoming millisecond to mach any time on or after the" +
+ " minute in which the " +
+ "millisecond falls"})
+ public DateRangeOnOrAfter(String precision) {
+ this.precision = DateRange.DateRangeBound.Precision.valueOf(precision.toUpperCase());
+ }
+
+ @Override
+ public DateRange apply(long value) {
+ Date date = new Date(value);
+ DateRange.DateRangeBound lower = DateRange.DateRangeBound.lowerBound(date, precision);
+ DateRange.DateRangeBound upper = DateRange.DateRangeBound.UNBOUNDED;
+ DateRange dateRange = new DateRange(lower, upper);
+ return dateRange;
+ }
+}
diff --git a/activitytype-cql/src/main/java/io/nosqlbench/activitytype/cql/datamappers/functions/to_daterange/DateRangeOnOrBefore.java b/activitytype-cql/src/main/java/io/nosqlbench/activitytype/cql/datamappers/functions/to_daterange/DateRangeOnOrBefore.java
new file mode 100644
index 000000000..0487c29ab
--- /dev/null
+++ b/activitytype-cql/src/main/java/io/nosqlbench/activitytype/cql/datamappers/functions/to_daterange/DateRangeOnOrBefore.java
@@ -0,0 +1,47 @@
+package io.nosqlbench.activitytype.cql.datamappers.functions.to_daterange;
+
+import com.datastax.driver.dse.search.DateRange;
+import io.nosqlbench.virtdata.annotations.Example;
+import io.nosqlbench.virtdata.annotations.ThreadSafeMapper;
+
+import java.util.Date;
+import java.util.function.Function;
+import java.util.function.LongFunction;
+
+/**
+ * Takes an input as a reference point in epoch time, and converts it to a DateRange,
+ * with the upper bound set to the upper bound of the precision and millisecond
+ * provided, and with no lower bound.
+ * You can use any of these precisions to control the bounds
+ * around the provided timestamp:
+ *
+ * - millisecond
+ * - second
+ * - minute
+ * - hour
+ * - day
+ * - month
+ * - year
+ *
+ */
+@ThreadSafeMapper
+public class DateRangeOnOrBefore implements LongFunction {
+
+ private final DateRange.DateRangeBound.Precision precision;
+
+ @Example({"DateRangeOnOrBefore('millisecond')}","Convert the incoming millisecond to match anything on or before it."})
+ @Example({"DateRangeOnOrBefore('minute')}","Convert the incoming millisecond to match anything on or before the minute in" +
+ " which the millisecond falls"})
+ public DateRangeOnOrBefore(String precision) {
+ this.precision = DateRange.DateRangeBound.Precision.valueOf(precision.toUpperCase());
+ }
+
+ @Override
+ public DateRange apply(long value) {
+ Date date = new Date(value);
+ DateRange.DateRangeBound lower = DateRange.DateRangeBound.UNBOUNDED;
+ DateRange.DateRangeBound upper = DateRange.DateRangeBound.upperBound(date,precision);
+ DateRange dateRange = new DateRange(lower, upper);
+ return dateRange;
+ }
+}
diff --git a/activitytype-cql/src/main/java/io/nosqlbench/activitytype/cql/datamappers/functions/to_daterange/DateRangeParser.java b/activitytype-cql/src/main/java/io/nosqlbench/activitytype/cql/datamappers/functions/to_daterange/DateRangeParser.java
new file mode 100644
index 000000000..970094627
--- /dev/null
+++ b/activitytype-cql/src/main/java/io/nosqlbench/activitytype/cql/datamappers/functions/to_daterange/DateRangeParser.java
@@ -0,0 +1,36 @@
+package io.nosqlbench.activitytype.cql.datamappers.functions.to_daterange;
+
+import com.datastax.driver.dse.search.DateRange;
+import io.nosqlbench.virtdata.annotations.Example;
+import io.nosqlbench.virtdata.annotations.ThreadSafeMapper;
+
+import java.text.ParseException;
+import java.util.Date;
+import java.util.function.Function;
+
+/**
+ * Parses the DateRange format according to Date Range Formatting.
+ * When possible it is more efficient to use the other DateRange methods since they do not require parsing.
+ */
+@ThreadSafeMapper
+public class DateRangeParser implements Function {
+
+ private final DateRange.DateRangeBound.Precision precision;
+
+ @Example({"DateRangeParser()}","Convert inputs like '[1970-01-01T00:00:00 TO 1970-01-01T00:00:00]' into " +
+ "DateRanges" +
+ " "})
+ public DateRangeParser(String precision) {
+ this.precision = DateRange.DateRangeBound.Precision.valueOf(precision.toUpperCase());
+ }
+
+ @Override
+ public DateRange apply(String value) {
+ try {
+ return DateRange.parse(value);
+ } catch (ParseException e) {
+ throw new RuntimeException("unable to parse date rage input '" + value + "': error:" + e.getMessage());
+ }
+ }
+}
diff --git a/activitytype-cql/src/test/java/io/nosqlbench/activitytype/cql/datamappers/functions/to_daterange/DateRangeFuncTest.java b/activitytype-cql/src/test/java/io/nosqlbench/activitytype/cql/datamappers/functions/to_daterange/DateRangeFuncTest.java
new file mode 100644
index 000000000..640f89a8e
--- /dev/null
+++ b/activitytype-cql/src/test/java/io/nosqlbench/activitytype/cql/datamappers/functions/to_daterange/DateRangeFuncTest.java
@@ -0,0 +1,59 @@
+package io.nosqlbench.activitytype.cql.datamappers.functions.to_daterange;
+
+import org.junit.Test;
+
+import java.util.function.Function;
+import java.util.function.LongFunction;
+import java.util.function.LongUnaryOperator;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class DateRangeFuncTest {
+
+ @Test
+ public void testDateRangeFuncs() {
+ LongFunction lf1 = value -> value;
+ DateRangeFunc function = new DateRangeFunc("second", lf1, lf1);
+
+ assertThat(function.apply(42L).toString())
+ .isEqualTo("[1970-01-01T00:00:00 TO 1970-01-01T00:00:00]");
+ assertThat(function.apply(42000L).toString())
+ .isEqualTo("[1970-01-01T00:00:42 TO 1970-01-01T00:00:42]");
+ assertThat(function.apply(42000000L).toString())
+ .isEqualTo("[1970-01-01T11:40:00 TO 1970-01-01T11:40:00]");
+ assertThat(function.apply(42000000000L).toString())
+ .isEqualTo("[1971-05-02T02:40:00 TO 1971-05-02T02:40:00]");
+ assertThat(function.apply(42000000000000L).toString())
+ .isEqualTo("[3300-12-05T02:40:00 TO 3300-12-05T02:40:00]");
+
+ LongUnaryOperator lf2 = value -> value;
+
+ function = new DateRangeFunc("second", lf2, lf2);
+ assertThat(function.apply(42L).toString())
+ .isEqualTo("[1970-01-01T00:00:00 TO 1970-01-01T00:00:00]");
+ assertThat(function.apply(42000L).toString())
+ .isEqualTo("[1970-01-01T00:00:42 TO 1970-01-01T00:00:42]");
+ assertThat(function.apply(42000000L).toString())
+ .isEqualTo("[1970-01-01T11:40:00 TO 1970-01-01T11:40:00]");
+ assertThat(function.apply(42000000000L).toString())
+ .isEqualTo("[1971-05-02T02:40:00 TO 1971-05-02T02:40:00]");
+ assertThat(function.apply(42000000000000L).toString())
+ .isEqualTo("[3300-12-05T02:40:00 TO 3300-12-05T02:40:00]");
+
+ Function lf3 = value -> value;
+
+ function = new DateRangeFunc("second", lf3, lf3);
+ assertThat(function.apply(42L).toString())
+ .isEqualTo("[1970-01-01T00:00:00 TO 1970-01-01T00:00:00]");
+ assertThat(function.apply(42000L).toString())
+ .isEqualTo("[1970-01-01T00:00:42 TO 1970-01-01T00:00:42]");
+ assertThat(function.apply(42000000L).toString())
+ .isEqualTo("[1970-01-01T11:40:00 TO 1970-01-01T11:40:00]");
+ assertThat(function.apply(42000000000L).toString())
+ .isEqualTo("[1971-05-02T02:40:00 TO 1971-05-02T02:40:00]");
+ assertThat(function.apply(42000000000000L).toString())
+ .isEqualTo("[3300-12-05T02:40:00 TO 3300-12-05T02:40:00]");
+
+ }
+
+}