This is an automated email from the ASF dual-hosted git repository.

xiazcy pushed a commit to branch graphbinary-add-datetime
in repository https://gitbox.apache.org/repos/asf/tinkerpop.git

commit 34f759f5907de1f9fc0b9e2763307a6f1b4ff277
Author: Yang Xia <[email protected]>
AuthorDate: Thu Sep 12 09:20:59 2024 -0700

    implement graphbinary datetime serializers for java and python
---
 .../gremlin/language/grammar/ArgumentVisitor.java  |   6 +-
 .../language/grammar/GenericLiteralVisitor.java    |   6 +-
 .../translator/DotNetTranslateVisitor.java         |   6 +-
 .../language/translator/GoTranslateVisitor.java    |   6 +-
 .../language/translator/JavaTranslateVisitor.java  |   9 +-
 .../translator/JavascriptTranslateVisitor.java     |   7 +-
 .../translator/PythonTranslateVisitor.java         |   6 +-
 .../gremlin/process/traversal/GremlinLang.java     |   5 +-
 .../traversal/dsl/graph/GraphTraversal.java        |  18 +--
 .../gremlin/process/traversal/dsl/graph/__.java    |  11 +-
 .../process/traversal/step/map/AsDateStep.java     |  24 ++-
 .../process/traversal/step/map/DateAddStep.java    |  49 ++++---
 .../process/traversal/step/map/DateDiffStep.java   |  23 +--
 .../gremlin/structure/io/binary/DataType.java      |   3 +-
 .../io/binary/TypeSerializerRegistry.java          |   5 +-
 ...TimeSerializer.java => DateTimeSerializer.java} |  20 ++-
 .../tinkerpop/gremlin/util/DatetimeHelper.java     |  26 ++--
 .../grammar/GeneralLiteralVisitorTest.java         |  39 +++--
 .../language/translator/GremlinTranslatorTest.java |  10 +-
 .../gremlin/process/traversal/OrderTest.java       |   9 +-
 .../process/traversal/step/map/AsDateStepTest.java |  16 +-
 .../traversal/step/map/DateAddStepTest.java        |  45 ++----
 .../traversal/step/map/DateDiffStepTest.java       |  44 ++----
 .../tinkerpop/gremlin/util/DatetimeHelperTest.java |  54 +++----
 .../src/main/python/gremlin_python/statics.py      |   8 -
 .../gremlin_python/structure/io/graphbinaryV4.py   |  45 +++++-
 .../src/main/python/radish/feature_steps.py        |   2 +-
 gremlin-python/src/main/python/radish/gremlin.py   |  19 ++-
 .../tests/structure/io/test_functionalityio.py     |  28 +---
 .../tests/structure/io/test_graphbinaryV4.py       |  27 +++-
 .../gremlin/test/features/map/AsDate.feature       | 162 ++++++++++-----------
 .../gremlin/test/features/map/DateAdd.feature      | 144 +++++++++---------
 .../util/ser/binary/types/sample/SamplePerson.java |   8 +-
 .../types/sample/SamplePersonSerializer.java       |   4 +-
 .../types/sample/SamplePersonSerializerTest.java   |   8 +-
 35 files changed, 461 insertions(+), 441 deletions(-)

diff --git 
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/language/grammar/ArgumentVisitor.java
 
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/language/grammar/ArgumentVisitor.java
index 2a3b214bba..b6b463b627 100644
--- 
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/language/grammar/ArgumentVisitor.java
+++ 
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/language/grammar/ArgumentVisitor.java
@@ -33,8 +33,8 @@ import org.apache.tinkerpop.gremlin.structure.VertexProperty;
 import org.apache.tinkerpop.gremlin.util.iterator.IteratorUtils;
 
 import java.lang.reflect.Array;
+import java.time.OffsetDateTime;
 import java.util.Comparator;
-import java.util.Date;
 import java.util.Map;
 import java.util.function.Function;
 
@@ -80,8 +80,8 @@ public class ArgumentVisitor extends 
DefaultGremlinBaseVisitor<Object> {
     /**
      * Wrapper to visit function for Date type.
      */
-    public Date parseDate(final GremlinParser.DateArgumentContext ctx) {
-        return (Date) visitDateArgument(ctx);
+    public OffsetDateTime parseDate(final GremlinParser.DateArgumentContext 
ctx) {
+        return (OffsetDateTime) visitDateArgument(ctx);
     }
 
     /**
diff --git 
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/language/grammar/GenericLiteralVisitor.java
 
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/language/grammar/GenericLiteralVisitor.java
index f29c563d3b..ced6c832d1 100644
--- 
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/language/grammar/GenericLiteralVisitor.java
+++ 
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/language/grammar/GenericLiteralVisitor.java
@@ -31,8 +31,8 @@ import org.apache.tinkerpop.gremlin.util.DatetimeHelper;
 
 import java.math.BigDecimal;
 import java.math.BigInteger;
+import java.time.OffsetDateTime;
 import java.util.ArrayList;
-import java.util.Date;
 import java.util.HashSet;
 import java.util.LinkedHashMap;
 import java.util.List;
@@ -86,8 +86,8 @@ public class GenericLiteralVisitor extends 
DefaultGremlinBaseVisitor<Object> {
     /**
      * Parse a Date based literal context and return the Date.
      */
-    public Date parseDate(final GremlinParser.DateLiteralContext dateLiteral) {
-        return (Date) visitDateLiteral(dateLiteral);
+    public OffsetDateTime parseDate(final GremlinParser.DateLiteralContext 
dateLiteral) {
+        return (OffsetDateTime) visitDateLiteral(dateLiteral);
     }
 
     /**
diff --git 
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/language/translator/DotNetTranslateVisitor.java
 
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/language/translator/DotNetTranslateVisitor.java
index 2701819624..c7ccb15323 100644
--- 
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/language/translator/DotNetTranslateVisitor.java
+++ 
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/language/translator/DotNetTranslateVisitor.java
@@ -26,6 +26,7 @@ import 
org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversal;
 import org.apache.tinkerpop.gremlin.structure.VertexProperty;
 import org.apache.tinkerpop.gremlin.util.DatetimeHelper;
 
+import java.time.OffsetDateTime;
 import java.util.Date;
 import java.util.HashMap;
 import java.util.List;
@@ -150,9 +151,10 @@ public class DotNetTranslateVisitor extends 
AbstractTranslateVisitor {
     public Void visitDateLiteral(final GremlinParser.DateLiteralContext ctx) {
         // child at 2 is the date argument to datetime() and comes enclosed in 
quotes
         final String dtString = ctx.getChild(2).getText();
-        final Date dt = 
DatetimeHelper.parse(removeFirstAndLastCharacters(dtString));
+        final OffsetDateTime dt = 
DatetimeHelper.parse(removeFirstAndLastCharacters(dtString));
+        // todo: update when dotnet datetime serializer is implemented
         sb.append("DateTimeOffset.FromUnixTimeMilliseconds(");
-        sb.append(dt.getTime());
+        sb.append(dt.toInstant().toEpochMilli());
         sb.append(")");
         return null;
     }
diff --git 
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/language/translator/GoTranslateVisitor.java
 
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/language/translator/GoTranslateVisitor.java
index 10eec9f3e0..10a8e7e4ab 100644
--- 
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/language/translator/GoTranslateVisitor.java
+++ 
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/language/translator/GoTranslateVisitor.java
@@ -26,6 +26,7 @@ import 
org.apache.tinkerpop.gremlin.language.grammar.GremlinParser;
 import org.apache.tinkerpop.gremlin.structure.VertexProperty;
 import org.apache.tinkerpop.gremlin.util.DatetimeHelper;
 
+import java.time.OffsetDateTime;
 import java.util.Date;
 import java.util.HashMap;
 import java.util.List;
@@ -47,8 +48,9 @@ public class GoTranslateVisitor extends 
AbstractTranslateVisitor {
     public Void visitDateLiteral(final GremlinParser.DateLiteralContext ctx) {
         // child at 2 is the date argument to datetime() and comes enclosed in 
quotes
         final String dtString = ctx.getChild(2).getText();
-        final Date dt = 
DatetimeHelper.parse(removeFirstAndLastCharacters(dtString));
-        sb.append("time.UnixMilli(" + dt.getTime() + ")");
+        final OffsetDateTime dt = 
DatetimeHelper.parse(removeFirstAndLastCharacters(dtString));
+        // todo: update when go datetime serializer is implemented
+        sb.append("time.UnixMilli(" + dt.toInstant().toEpochMilli() + ")");
         return null;
     }
 
diff --git 
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/language/translator/JavaTranslateVisitor.java
 
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/language/translator/JavaTranslateVisitor.java
index 9eb0e945e5..9830d8c95c 100644
--- 
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/language/translator/JavaTranslateVisitor.java
+++ 
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/language/translator/JavaTranslateVisitor.java
@@ -24,6 +24,7 @@ import 
org.apache.tinkerpop.gremlin.language.grammar.GremlinParser;
 import org.apache.tinkerpop.gremlin.structure.util.reference.ReferenceVertex;
 import org.apache.tinkerpop.gremlin.util.DatetimeHelper;
 
+import java.time.OffsetDateTime;
 import java.util.Date;
 import java.util.List;
 import java.util.stream.Collectors;
@@ -144,10 +145,10 @@ public class JavaTranslateVisitor extends 
AbstractTranslateVisitor {
     public Void visitDateLiteral(final GremlinParser.DateLiteralContext ctx) {
         // child at 2 is the date argument to datetime() and comes enclosed in 
quotes
         final String dtString = ctx.getChild(2).getText();
-        final Date dt = 
DatetimeHelper.parse(removeFirstAndLastCharacters(dtString));
-        sb.append("new Date(");
-        sb.append(dt.getTime());
-        sb.append(")");
+        final OffsetDateTime dt = 
DatetimeHelper.parse(removeFirstAndLastCharacters(dtString));
+        sb.append("OffsetDateTime.parse(\"");
+        sb.append(dt);
+        sb.append("\")");
         return null;
     }
 
diff --git 
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/language/translator/JavascriptTranslateVisitor.java
 
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/language/translator/JavascriptTranslateVisitor.java
index 01d094fb68..830d6211d7 100644
--- 
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/language/translator/JavascriptTranslateVisitor.java
+++ 
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/language/translator/JavascriptTranslateVisitor.java
@@ -27,7 +27,7 @@ import 
org.apache.tinkerpop.gremlin.process.traversal.TraversalStrategy;
 import org.apache.tinkerpop.gremlin.structure.VertexProperty;
 import org.apache.tinkerpop.gremlin.util.DatetimeHelper;
 
-import java.util.Date;
+import java.time.OffsetDateTime;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -133,9 +133,10 @@ public class JavascriptTranslateVisitor extends 
AbstractTranslateVisitor {
     public Void visitDateLiteral(final GremlinParser.DateLiteralContext ctx) {
         // child at 2 is the date argument to datetime() and comes enclosed in 
quotes
         final String dtString = ctx.getChild(2).getText();
-        final Date dt = 
DatetimeHelper.parse(removeFirstAndLastCharacters(dtString));
+        final OffsetDateTime dt = 
DatetimeHelper.parse(removeFirstAndLastCharacters(dtString));
+        // todo: update when javascript datetime serializer is implemented
         sb.append("new Date(");
-        sb.append(dt.getTime());
+        sb.append(dt.toInstant().toEpochMilli());
         sb.append(")");
         return null;
     }
diff --git 
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/language/translator/PythonTranslateVisitor.java
 
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/language/translator/PythonTranslateVisitor.java
index 092c41fe5e..46cebbbc4d 100644
--- 
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/language/translator/PythonTranslateVisitor.java
+++ 
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/language/translator/PythonTranslateVisitor.java
@@ -27,7 +27,7 @@ import org.apache.tinkerpop.gremlin.structure.VertexProperty;
 import org.apache.tinkerpop.gremlin.util.DatetimeHelper;
 
 import java.math.BigInteger;
-import java.util.Date;
+import java.time.OffsetDateTime;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -161,8 +161,8 @@ public class PythonTranslateVisitor extends 
AbstractTranslateVisitor {
     public Void visitDateLiteral(final GremlinParser.DateLiteralContext ctx) {
         // child at 2 is the date argument to datetime() and comes enclosed in 
quotes
         final String dtString = ctx.getChild(2).getText();
-        final Date dt = 
DatetimeHelper.parse(removeFirstAndLastCharacters(dtString));
-        sb.append("datetime.datetime.utcfromtimestamp(" + dt.getTime() + " / 
1000.0)");
+        final OffsetDateTime dt = 
DatetimeHelper.parse(removeFirstAndLastCharacters(dtString));
+        sb.append("datetime.datetime.fromtimestamp(" + dt.toEpochSecond() + 
").astimezone(datetime.timezone.utc)");
         return null;
     }
 
diff --git 
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/GremlinLang.java
 
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/GremlinLang.java
index 1b50dee8c7..4fd9eed353 100644
--- 
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/GremlinLang.java
+++ 
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/GremlinLang.java
@@ -34,6 +34,7 @@ import javax.lang.model.SourceVersion;
 import java.io.Serializable;
 import java.math.BigDecimal;
 import java.math.BigInteger;
+import java.time.OffsetDateTime;
 import java.util.ArrayList;
 import java.util.Date;
 import java.util.HashMap;
@@ -134,8 +135,8 @@ public class GremlinLang implements Cloneable, Serializable 
{
         if (arg instanceof BigDecimal)
             return String.format("%sM", arg);
 
-        if (arg instanceof Date)
-            return String.format("datetime(\"%s\")", format(((Date) 
arg).toInstant()));
+        if (arg instanceof OffsetDateTime)
+            return String.format("datetime(\"%s\")", format(((OffsetDateTime) 
arg).toInstant()));
 
         if (arg instanceof Enum) {
             // special handling for enums with additional interfaces
diff --git 
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.java
 
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.java
index df8e75f0dd..36dcc5dd5f 100644
--- 
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.java
+++ 
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.java
@@ -205,12 +205,12 @@ import org.apache.tinkerpop.gremlin.structure.Vertex;
 import org.apache.tinkerpop.gremlin.structure.VertexProperty;
 import org.apache.tinkerpop.gremlin.util.function.ConstantSupplier;
 
+import java.time.OffsetDateTime;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.Comparator;
-import java.util.Date;
 import java.util.Iterator;
 import java.util.LinkedHashMap;
 import java.util.List;
@@ -1841,49 +1841,49 @@ public interface GraphTraversal<S, E> extends 
Traversal<S, E> {
     }
 
     /**
-     * Parse value of the incoming traverser as an ISO-8601 {@link Date}.
+     * Parse value of the incoming traverser as an ISO-8601 {@link 
OffsetDateTime}.
      *
      * @return the traversal with an appended {@link AsDateStep}.
      * @see <a 
href="http://tinkerpop.apache.org/docs/${project.version}/reference/#asDate-step";
 target="_blank">Reference Documentation - asDate Step</a>
      * @since 3.7.1
      */
-    public default GraphTraversal<S, Date> asDate() {
+    public default GraphTraversal<S, OffsetDateTime> asDate() {
         this.asAdmin().getGremlinLang().addStep(Symbols.asDate);
         return this.asAdmin().addStep(new AsDateStep<>(this.asAdmin()));
     }
 
     /**
-     * Increase value of input {@link Date}.
+     * Increase value of input {@link OffsetDateTime}.
      *
      * @return the traversal with an appended {@link DateAddStep}.
      * @see <a 
href="http://tinkerpop.apache.org/docs/${project.version}/reference/#dateAdd-step";
 target="_blank">Reference Documentation - dateAdd Step</a>
      * @since 3.7.1
      */
-    public default GraphTraversal<S, Date> dateAdd(final DT dateToken, final 
int value) {
+    public default GraphTraversal<S, OffsetDateTime> dateAdd(final DT 
dateToken, final int value) {
         this.asAdmin().getGremlinLang().addStep(Symbols.dateAdd, dateToken, 
value);
         return this.asAdmin().addStep(new DateAddStep<>(this.asAdmin(), 
dateToken, value));
     }
 
     /**
-     * Returns the difference between two {@link Date} in epoch time.
+     * Returns the difference between two {@link OffsetDateTime} in epoch time.
      *
      * @return the traversal with an appended {@link DateDiffStep}.
      * @see <a 
href="http://tinkerpop.apache.org/docs/${project.version}/reference/#dateDiff-step";
 target="_blank">Reference Documentation - dateDiff Step</a>
      * @since 3.7.1
      */
-    public default GraphTraversal<S, Long> dateDiff(final Date value) {
+    public default GraphTraversal<S, Long> dateDiff(final OffsetDateTime 
value) {
         this.asAdmin().getGremlinLang().addStep(Symbols.dateDiff, value);
         return this.asAdmin().addStep(new DateDiffStep<>(this.asAdmin(), 
value));
     }
 
     /**
-     * Returns the difference between two {@link Date} in epoch time.
+     * Returns the difference between two {@link OffsetDateTime} in epoch time.
      *
      * @return the traversal with an appended {@link DateDiffStep}.
      * @see <a 
href="http://tinkerpop.apache.org/docs/${project.version}/reference/#dateDiff-step";
 target="_blank">Reference Documentation - dateDiff Step</a>
      * @since 3.7.1
      */
-    public default GraphTraversal<S, Long> dateDiff(final Traversal<?, Date> 
dateTraversal) {
+    public default GraphTraversal<S, Long> dateDiff(final Traversal<?, 
OffsetDateTime> dateTraversal) {
         this.asAdmin().getGremlinLang().addStep(Symbols.dateDiff, 
dateTraversal);
         return this.asAdmin().addStep(new DateDiffStep<>(this.asAdmin(), 
dateTraversal));
     }
diff --git 
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/__.java
 
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/__.java
index 14a0e9dfb5..57776db82e 100644
--- 
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/__.java
+++ 
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/__.java
@@ -36,6 +36,7 @@ import org.apache.tinkerpop.gremlin.structure.T;
 import org.apache.tinkerpop.gremlin.structure.Vertex;
 import org.apache.tinkerpop.gremlin.structure.VertexProperty;
 
+import java.time.OffsetDateTime;
 import java.util.Collection;
 import java.util.Date;
 import java.util.Iterator;
@@ -773,28 +774,28 @@ public class __ {
     /**
      * @see GraphTraversal#asDate()
      */
-    public static <A> GraphTraversal<A, Date> asDate() {
+    public static <A> GraphTraversal<A, OffsetDateTime> asDate() {
         return __.<A>start().asDate();
     }
 
     /**
      * @see GraphTraversal#dateAdd(DT, int)
      */
-    public static <A> GraphTraversal<A, Date> dateAdd(final DT dateToken, 
final int value) {
+    public static <A> GraphTraversal<A, OffsetDateTime> dateAdd(final DT 
dateToken, final int value) {
         return __.<A>start().dateAdd(dateToken, value);
     }
 
     /**
-     * @see GraphTraversal#dateDiff(Date)
+     * @see GraphTraversal#dateDiff(OffsetDateTime)
      */
-    public static <A> GraphTraversal<A, Long> dateDiff(final Date value) {
+    public static <A> GraphTraversal<A, Long> dateDiff(final OffsetDateTime 
value) {
         return __.<A>start().dateDiff(value);
     }
 
     /**
      * @see GraphTraversal#dateDiff(Traversal)
      */
-    public static <A> GraphTraversal<A, Long> dateDiff(final Traversal<?, 
Date> dateTraversal) {
+    public static <A> GraphTraversal<A, Long> dateDiff(final Traversal<?, 
OffsetDateTime> dateTraversal) {
         return __.<A>start().dateDiff(dateTraversal);
     }
 
diff --git 
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/AsDateStep.java
 
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/AsDateStep.java
index 22ea8db3f3..1359ee5d82 100644
--- 
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/AsDateStep.java
+++ 
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/AsDateStep.java
@@ -20,17 +20,15 @@ package 
org.apache.tinkerpop.gremlin.process.traversal.step.map;
 
 import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
 import org.apache.tinkerpop.gremlin.process.traversal.Traverser;
-import org.apache.tinkerpop.gremlin.process.traversal.step.TraversalParent;
-import 
org.apache.tinkerpop.gremlin.process.traversal.step.sideEffect.InjectStep;
 import 
org.apache.tinkerpop.gremlin.process.traversal.traverser.TraverserRequirement;
-import org.apache.tinkerpop.gremlin.process.traversal.util.TraversalUtil;
 import org.apache.tinkerpop.gremlin.structure.util.StringFactory;
 import org.apache.tinkerpop.gremlin.util.DatetimeHelper;
 
+import java.time.Instant;
+import java.time.OffsetDateTime;
+import java.time.ZoneOffset;
 import java.time.format.DateTimeParseException;
 import java.util.Collections;
-import java.util.Date;
-import java.util.List;
 import java.util.Set;
 
 /**
@@ -38,32 +36,32 @@ import java.util.Set;
  *
  * @author Valentyn Kahamlyk
  */
-public final class AsDateStep<S> extends ScalarMapStep<S, Date> {
+public final class AsDateStep<S> extends ScalarMapStep<S, OffsetDateTime> {
 
     public AsDateStep(final Traversal.Admin traversal) {
         super(traversal);
     }
 
     @Override
-    protected Date map(final Traverser.Admin<S> traverser) {
+    protected OffsetDateTime map(final Traverser.Admin<S> traverser) {
         final Object object = traverser.get();
         if (object == null)
-            throw new IllegalArgumentException("Can't parse null as Date.");
-        if (object instanceof Date)
-            return (Date) object;
+            throw new IllegalArgumentException("Can't parse null as 
DateTime.");
+        if (object instanceof OffsetDateTime)
+            return (OffsetDateTime) object;
         if (object instanceof Number)
             // numbers handled as milliseconds since January 1, 1970, 00:00:00 
GMT.
-            return new Date(((Number) object).longValue());
+            return OffsetDateTime.ofInstant(Instant.ofEpochMilli(((Number) 
object).longValue()), ZoneOffset.UTC);
         if (object instanceof String) {
             try {
                 return DatetimeHelper.parse((String) object);
             }
             catch (DateTimeParseException e) {
-                throw new IllegalArgumentException("Can't parse " + object + " 
as Date.");
+                throw new IllegalArgumentException("Can't parse " + object + " 
as OffsetDateTime.");
             }
         }
 
-        throw new IllegalArgumentException("Can't parse " + 
object.getClass().getName() + " as Date.");
+        throw new IllegalArgumentException("Can't parse " + 
object.getClass().getName() + " as OffsetDateTime.");
     }
 
     @Override
diff --git 
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/DateAddStep.java
 
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/DateAddStep.java
index ef45701d1f..9dcedcd8c6 100644
--- 
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/DateAddStep.java
+++ 
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/DateAddStep.java
@@ -24,11 +24,9 @@ import 
org.apache.tinkerpop.gremlin.process.traversal.Traverser;
 import 
org.apache.tinkerpop.gremlin.process.traversal.traverser.TraverserRequirement;
 import org.apache.tinkerpop.gremlin.structure.util.StringFactory;
 
-import java.util.Calendar;
+import java.time.Duration;
+import java.time.OffsetDateTime;
 import java.util.Collections;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.Map;
 import java.util.Set;
 
 /**
@@ -36,16 +34,7 @@ import java.util.Set;
  *
  * @author Valentyn Kahamlyk
  */
-public final class DateAddStep<S> extends ScalarMapStep<S, Date> {
-
-    final static Map<DT, Integer> DTtoCalendar = new HashMap<>();
-
-    static {
-        DTtoCalendar.put(DT.second, Calendar.SECOND);
-        DTtoCalendar.put(DT.minute, Calendar.MINUTE);
-        DTtoCalendar.put(DT.hour, Calendar.HOUR_OF_DAY);
-        DTtoCalendar.put(DT.day, Calendar.DAY_OF_MONTH);
-    }
+public final class DateAddStep<S> extends ScalarMapStep<S, OffsetDateTime> {
 
     private DT dateToken;
     private int value;
@@ -57,16 +46,32 @@ public final class DateAddStep<S> extends ScalarMapStep<S, 
Date> {
     }
 
     @Override
-    protected Date map(final Traverser.Admin<S> traverser) {
+    protected OffsetDateTime map(final Traverser.Admin<S> traverser) {
         final Object object = traverser.get();
 
-        if (!(object instanceof Date)) throw new 
IllegalArgumentException("dateAdd accept only Date.");
-
-        final Calendar cal = Calendar.getInstance();
-        cal.setTime((Date) object);
-        cal.add(DTtoCalendar.get(dateToken), value);
-
-        return cal.getTime();
+        if (!(object instanceof OffsetDateTime)) throw new 
IllegalArgumentException("dateAdd accept only DateTime.");
+
+        OffsetDateTime date = (OffsetDateTime) object;
+        OffsetDateTime new_date;
+
+        switch (dateToken) {
+            case second:
+                new_date = date.plus(Duration.ofSeconds(value));
+                break;
+            case minute:
+                new_date = date.plus(Duration.ofMinutes(value));
+                break;
+            case hour:
+                new_date = date.plus(Duration.ofHours(value));
+                break;
+            case day:
+                new_date = date.plus(Duration.ofDays(value));
+                break;
+            default:
+                throw new IllegalArgumentException("DT tokens should only be 
second, minute, hour, or day.");
+        }
+
+        return new_date;
     }
 
     @Override
diff --git 
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/DateDiffStep.java
 
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/DateDiffStep.java
index d15d461845..63c2c93ee0 100644
--- 
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/DateDiffStep.java
+++ 
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/DateDiffStep.java
@@ -25,6 +25,7 @@ import 
org.apache.tinkerpop.gremlin.process.traversal.traverser.TraverserRequire
 import org.apache.tinkerpop.gremlin.process.traversal.util.TraversalUtil;
 import org.apache.tinkerpop.gremlin.structure.util.StringFactory;
 
+import java.time.OffsetDateTime;
 import java.util.Collections;
 import java.util.Date;
 import java.util.Set;
@@ -36,15 +37,15 @@ import java.util.Set;
  */
 public final class DateDiffStep<S> extends ScalarMapStep<S, Long> implements 
TraversalParent {
 
-    private Date value;
-    private Traversal.Admin<S, Date> dateTraversal;
+    private OffsetDateTime value;
+    private Traversal.Admin<S, OffsetDateTime> dateTraversal;
 
-    public DateDiffStep(final Traversal.Admin traversal, final Date value) {
+    public DateDiffStep(final Traversal.Admin traversal, final OffsetDateTime 
value) {
         super(traversal);
         this.value = value;
     }
 
-    public DateDiffStep(final Traversal.Admin traversal, final Traversal<?, 
Date> dateTraversal) {
+    public DateDiffStep(final Traversal.Admin traversal, final Traversal<?, 
OffsetDateTime> dateTraversal) {
         super(traversal);
         this.dateTraversal = this.integrateChild(dateTraversal.asAdmin());
     }
@@ -53,17 +54,17 @@ public final class DateDiffStep<S> extends ScalarMapStep<S, 
Long> implements Tra
     protected Long map(final Traverser.Admin<S> traverser) {
         final Object object = traverser.get();
 
-        if (!(object instanceof Date))
+        if (!(object instanceof OffsetDateTime))
             throw new IllegalArgumentException(
-                    String.format("DateDiff can only take Date as argument, 
encountered %s", object.getClass()));
+                    String.format("DateDiff can only take DateTime as 
argument, encountered %s", object.getClass()));
 
-        final Date otherDate = value != null ? value :
+        final OffsetDateTime otherDate = value != null ? value :
                 dateTraversal != null ? TraversalUtil.apply(traverser, 
dateTraversal) : null;
 
         // let's not throw exception and assume null date == 0
-        final long otherDateMs = otherDate == null ? 0 : otherDate.getTime();
+        final long otherDateMs = otherDate == null ? 0 : 
otherDate.toEpochSecond();
 
-        return (((Date) object).getTime() - otherDateMs) / 1000;
+        return (((OffsetDateTime) object).toEpochSecond() - otherDateMs);
     }
 
     @Override
@@ -96,11 +97,11 @@ public final class DateDiffStep<S> extends ScalarMapStep<S, 
Long> implements Tra
         return StringFactory.stepString(this);
     }
 
-    public Date getValue() {
+    public OffsetDateTime getValue() {
         return this.value;
     }
 
-    public Traversal.Admin<S, Date> getDateTraversal() {
+    public Traversal.Admin<S, OffsetDateTime> getDateTraversal() {
         return this.dateTraversal;
     }
 }
diff --git 
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/binary/DataType.java
 
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/binary/DataType.java
index 4f52b6069d..90548c4cdd 100644
--- 
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/binary/DataType.java
+++ 
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/binary/DataType.java
@@ -28,7 +28,7 @@ public enum DataType {
     INT(0x01),
     LONG(0x02),
     STRING(0X03),
-    DATETIME(0X04),  // todo: to be updated from OffsetDateTime
+    DATETIME(0X04),
     DOUBLE(0X07),
     FLOAT(0X08),
     LIST(0X09),
@@ -55,7 +55,6 @@ public enum DataType {
 
     CHAR(0X80),
     DURATION(0X81),
-    OFFSETDATETIME(0X88),
 
     CUSTOM(0),
     MARKER(0XFD),
diff --git 
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/binary/TypeSerializerRegistry.java
 
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/binary/TypeSerializerRegistry.java
index 427de19c28..db6193d266 100644
--- 
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/binary/TypeSerializerRegistry.java
+++ 
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/binary/TypeSerializerRegistry.java
@@ -44,7 +44,7 @@ import 
org.apache.tinkerpop.gremlin.structure.io.binary.types.GraphSerializer;
 import org.apache.tinkerpop.gremlin.structure.io.binary.types.ListSerializer;
 import 
org.apache.tinkerpop.gremlin.structure.io.binary.types.MapEntrySerializer;
 import org.apache.tinkerpop.gremlin.structure.io.binary.types.MapSerializer;
-import 
org.apache.tinkerpop.gremlin.structure.io.binary.types.OffsetDateTimeSerializer;
+import 
org.apache.tinkerpop.gremlin.structure.io.binary.types.DateTimeSerializer;
 import org.apache.tinkerpop.gremlin.structure.io.binary.types.PathSerializer;
 import 
org.apache.tinkerpop.gremlin.structure.io.binary.types.PropertySerializer;
 import org.apache.tinkerpop.gremlin.structure.io.binary.types.SetSerializer;
@@ -120,8 +120,7 @@ public class TypeSerializerRegistry {
 
             new RegistryEntry<>(Character.class, new CharSerializer()),
             new RegistryEntry<>(Duration.class, new DurationSerializer()),
-            new RegistryEntry<>(OffsetDateTime.class, new 
OffsetDateTimeSerializer()),  //todo: to be updated to DateTime serializer
-
+            new RegistryEntry<>(OffsetDateTime.class, new DateTimeSerializer())
     };
 
     public static final TypeSerializerRegistry INSTANCE = build().create();
diff --git 
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/binary/types/OffsetDateTimeSerializer.java
 
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/binary/types/DateTimeSerializer.java
similarity index 68%
rename from 
gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/binary/types/OffsetDateTimeSerializer.java
rename to 
gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/binary/types/DateTimeSerializer.java
index 96019c1a20..416ceb8aa1 100644
--- 
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/binary/types/OffsetDateTimeSerializer.java
+++ 
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/binary/types/DateTimeSerializer.java
@@ -24,29 +24,33 @@ import 
org.apache.tinkerpop.gremlin.structure.io.binary.GraphBinaryWriter;
 import org.apache.tinkerpop.gremlin.structure.io.Buffer;
 
 import java.io.IOException;
+import java.time.LocalDate;
 import java.time.LocalDateTime;
+import java.time.LocalTime;
 import java.time.OffsetDateTime;
 import java.time.ZoneOffset;
 
 /**
  * @author Stephen Mallette (http://stephen.genoprime.com)
  */
-public class OffsetDateTimeSerializer extends 
SimpleTypeSerializer<OffsetDateTime> {
-    public OffsetDateTimeSerializer() {
-        super(DataType.OFFSETDATETIME);
+public class DateTimeSerializer extends SimpleTypeSerializer<OffsetDateTime> {
+    public DateTimeSerializer() {
+        super(DataType.DATETIME);
     }
 
     @Override
     protected OffsetDateTime readValue(final Buffer buffer, final 
GraphBinaryReader context) throws IOException {
-        // todo: Updates needed for deserializing these values as their 
serializers are removed
-        final LocalDateTime ldt = context.readValue(buffer, 
LocalDateTime.class, false);
-        final ZoneOffset zo = context.readValue(buffer, ZoneOffset.class, 
false);
+        final LocalDate localDate = LocalDate.of(buffer.readInt(), 
buffer.readByte(), buffer.readByte());
+        final LocalTime localTime = LocalTime.ofNanoOfDay(buffer.readLong());
+        final LocalDateTime ldt = LocalDateTime.of(localDate, localTime);
+        final ZoneOffset zo = ZoneOffset.ofTotalSeconds(buffer.readInt());
         return OffsetDateTime.of(ldt, zo);
     }
 
     @Override
     protected void writeValue(final OffsetDateTime value, final Buffer buffer, 
final GraphBinaryWriter context) throws IOException {
-        context.writeValue(value.toLocalDateTime(), buffer, false);
-        context.writeValue(value.getOffset(), buffer, false);
+        
buffer.writeInt(value.getYear()).writeByte(value.getMonthValue()).writeByte(value.getDayOfMonth());
+        buffer.writeLong(value.toLocalTime().toNanoOfDay());
+        buffer.writeInt(value.getOffset().getTotalSeconds());
     }
 }
diff --git 
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/util/DatetimeHelper.java
 
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/util/DatetimeHelper.java
index 31334117b0..88f7e1c332 100644
--- 
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/util/DatetimeHelper.java
+++ 
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/util/DatetimeHelper.java
@@ -22,7 +22,11 @@ import java.time.Instant;
 import java.time.LocalDate;
 import java.time.LocalDateTime;
 import java.time.LocalTime;
+import java.time.Month;
+import java.time.OffsetDateTime;
+import java.time.Year;
 import java.time.YearMonth;
+import java.time.ZoneOffset;
 import java.time.ZonedDateTime;
 import java.time.format.DateTimeFormatter;
 import java.time.format.DateTimeFormatterBuilder;
@@ -93,45 +97,41 @@ public final class DatetimeHelper {
      * </ul>>
      *
      */
-    public static Date parse(final String d) {
+    public static OffsetDateTime parse(final String d) {
         final TemporalAccessor t = formatter.parse(d);
 
         if (!t.isSupported(ChronoField.HOUR_OF_DAY)) {
             // no hours field so it must be a Date or a YearMonth
             if (!t.isSupported(ChronoField.DAY_OF_MONTH)) {
                 // must be a YearMonth coz no day
-                return 
Date.from(YearMonth.from(t).atDay(1).atStartOfDay(UTC).toInstant());
+                return OffsetDateTime.of(LocalDate.of(Year.from(t).getValue(), 
Month.from(t), 1), LocalTime.MIDNIGHT, UTC);
             } else {
                 // must be a Date as the day is present
-                return 
Date.from(Instant.ofEpochSecond(LocalDate.from(t).atStartOfDay().toEpochSecond(UTC)));
+                return OffsetDateTime.of(LocalDate.from(t), 
LocalTime.MIDNIGHT, UTC);
             }
         } else if (!t.isSupported(ChronoField.MONTH_OF_YEAR)) {
             // no month field so must be a Time
-            final Instant timeOnEpochDay = LocalDate.ofEpochDay(0)
-                    .atTime(LocalTime.from(t))
-                    .atZone(UTC)
-                    .toInstant();
-            return Date.from(timeOnEpochDay);
+            return OffsetDateTime.of(LocalDate.ofEpochDay(0), 
LocalTime.from(t), UTC);
         } else if (t.isSupported(ChronoField.OFFSET_SECONDS)) {
             // has all datetime components including an offset
-            return Date.from(ZonedDateTime.from(t).toInstant());
+            return OffsetDateTime.of(LocalDateTime.from(t), 
ZoneOffset.from(t));
         } else {
             // has all datetime components but no offset so throw in some UTC
-            return Date.from(ZonedDateTime.of(LocalDateTime.from(t), 
UTC).toInstant());
+            return OffsetDateTime.of(LocalDateTime.from(t), UTC);
         }
     }
 
     /**
      * A proxy call to {@link #parse(String)} but allows for syntax similar to 
Gremlin grammar of {@code datetime()}.
      */
-    public static Date datetime(final String d) {
+    public static OffsetDateTime datetime(final String d) {
         return parse(d);
     }
 
     /**
      * A proxy allows for syntax similar to Gremlin grammar of {@code 
datetime()}.
      */
-    public static Date datetime() {
-        return new Date();
+    public static OffsetDateTime datetime() {
+        return OffsetDateTime.now();
     }
 }
diff --git 
a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/language/grammar/GeneralLiteralVisitorTest.java
 
b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/language/grammar/GeneralLiteralVisitorTest.java
index dea62a082c..e9d2f5d2a5 100644
--- 
a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/language/grammar/GeneralLiteralVisitorTest.java
+++ 
b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/language/grammar/GeneralLiteralVisitorTest.java
@@ -31,17 +31,17 @@ import org.junit.runners.Parameterized;
 import java.lang.reflect.Constructor;
 import java.math.BigDecimal;
 import java.math.BigInteger;
-import java.time.ZoneId;
+import java.time.LocalDateTime;
+import java.time.OffsetDateTime;
 import java.time.ZoneOffset;
-import java.time.ZonedDateTime;
 import java.util.ArrayList;
 import java.util.Arrays;
-import java.util.Date;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
 
+import static java.time.ZoneOffset.UTC;
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.hamcrest.core.IsInstanceOf.instanceOf;
 import static org.hamcrest.number.OrderingComparison.greaterThanOrEqualTo;
@@ -448,29 +448,28 @@ public class GeneralLiteralVisitorTest {
 
     @RunWith(Parameterized.class)
     public static class ValidDatetimeLiteralTest {
-        private static final ZoneId UTC = ZoneId.of("Z");
 
         @Parameterized.Parameter(value = 0)
         public String script;
 
         @Parameterized.Parameter(value = 1)
-        public Date expected;
+        public OffsetDateTime expected;
 
         @Parameterized.Parameters(name = "{0}")
         public static Iterable<Object[]> generateTestParameters() {
             return Arrays.asList(new Object[][]{
-                    {"datetime('2018-03-22T00:35:44.741Z')", 
Date.from(ZonedDateTime.of(2018, 03, 22, 00, 35, 44, 741000000, 
UTC).toInstant())},
-                    {"datetime('2018-03-22T00:35:44.741-0000')", 
Date.from(ZonedDateTime.of(2018, 03, 22, 00, 35, 44, 741000000, 
UTC).toInstant())},
-                    {"datetime('2018-03-22T00:35:44.741+0000')", 
Date.from(ZonedDateTime.of(2018, 03, 22, 00, 35, 44, 741000000, 
UTC).toInstant())},
-                    {"datetime('2018-03-22T00:35:44.741-0300')", 
Date.from(ZonedDateTime.of(2018, 03, 22, 00, 35, 44, 741000000, 
ZoneOffset.ofHours(-3)).toInstant())},
-                    {"datetime('2018-03-22T00:35:44.741+1600')", 
Date.from(ZonedDateTime.of(2018, 03, 22, 00, 35, 44, 741000000, 
ZoneOffset.ofHours(16)).toInstant())},
-                    {"datetime('2018-03-22T00:35:44.741')", 
Date.from(ZonedDateTime.of(2018, 03, 22, 00, 35, 44, 741000000, 
UTC).toInstant())},
-                    {"datetime('2018-03-22T00:35:44Z')", 
Date.from(ZonedDateTime.of(2018, 03, 22, 00, 35, 44, 0, UTC).toInstant())},
-                    {"datetime('2018-03-22T00:35:44')", 
Date.from(ZonedDateTime.of(2018, 03, 22, 00, 35, 44, 0, UTC).toInstant())},
-                    {"datetime('2018-03-22')", 
Date.from(ZonedDateTime.of(2018, 03, 22, 0, 0, 0, 0, UTC).toInstant())},
-                    {"datetime('1018-03-22')", 
Date.from(ZonedDateTime.of(1018, 03, 22, 0, 0, 0, 0, UTC).toInstant())},
-                    {"datetime('9018-03-22')", 
Date.from(ZonedDateTime.of(9018, 03, 22, 0, 0, 0, 0, UTC).toInstant())},
-                    {"datetime('1000-001')", Date.from(ZonedDateTime.of(1000, 
1, 1, 0, 0, 0, 0, UTC).toInstant())},
+                    {"datetime('2018-03-22T00:35:44.741Z')", 
OffsetDateTime.of(LocalDateTime.of(2018, 03, 22, 00, 35, 44, 741000000), UTC)},
+                    {"datetime('2018-03-22T00:35:44.741-0000')", 
OffsetDateTime.of(LocalDateTime.of(2018, 03, 22, 00, 35, 44, 741000000), UTC)},
+                    {"datetime('2018-03-22T00:35:44.741+0000')", 
OffsetDateTime.of(LocalDateTime.of(2018, 03, 22, 00, 35, 44, 741000000), UTC)},
+                    {"datetime('2018-03-22T00:35:44.741-0300')", 
OffsetDateTime.of(LocalDateTime.of(2018, 03, 22, 00, 35, 44, 741000000), 
ZoneOffset.ofHours(-3))},
+                    {"datetime('2018-03-22T00:35:44.741+1600')", 
OffsetDateTime.of(LocalDateTime.of(2018, 03, 22, 00, 35, 44, 741000000), 
ZoneOffset.ofHours(16))},
+                    {"datetime('2018-03-22T00:35:44.741')", 
OffsetDateTime.of(LocalDateTime.of(2018, 03, 22, 00, 35, 44, 741000000), UTC)},
+                    {"datetime('2018-03-22T00:35:44Z')", 
OffsetDateTime.of(LocalDateTime.of(2018, 03, 22, 00, 35, 44, 0), UTC)},
+                    {"datetime('2018-03-22T00:35:44')", 
OffsetDateTime.of(LocalDateTime.of(2018, 03, 22, 00, 35, 44, 0), UTC)},
+                    {"datetime('2018-03-22')", 
OffsetDateTime.of(LocalDateTime.of(2018, 03, 22, 0, 0, 0, 0), UTC)},
+                    {"datetime('1018-03-22')", 
OffsetDateTime.of(LocalDateTime.of(1018, 03, 22, 0, 0, 0, 0), UTC)},
+                    {"datetime('9018-03-22')", 
OffsetDateTime.of(LocalDateTime.of(9018, 03, 22, 0, 0, 0, 0), UTC)},
+                    {"datetime('1000-001')", 
OffsetDateTime.of(LocalDateTime.of(1000, 1, 1, 0, 0, 0, 0), UTC)},
             });
         }
 
@@ -480,7 +479,7 @@ public class GeneralLiteralVisitorTest {
             final GremlinParser parser = new GremlinParser(new 
CommonTokenStream(lexer));
             final GremlinParser.DateLiteralContext ctx = parser.dateLiteral();
 
-            final Date dt = (Date) new GenericLiteralVisitor(new 
GremlinAntlrToJava()).visitDateLiteral(ctx);
+            final OffsetDateTime dt = (OffsetDateTime) new 
GenericLiteralVisitor(new GremlinAntlrToJava()).visitDateLiteral(ctx);
             assertEquals(expected, dt);
         }
     }
@@ -492,8 +491,8 @@ public class GeneralLiteralVisitorTest {
             final GremlinParser parser = new GremlinParser(new 
CommonTokenStream(lexer));
             final GremlinParser.DateLiteralContext ctx = parser.dateLiteral();
 
-            final Date dt = (Date) new GenericLiteralVisitor(new 
GremlinAntlrToJava()).visitDateLiteral(ctx);
-            assertTrue(new Date().getTime() - dt.getTime() < 1000);
+            final OffsetDateTime dt = (OffsetDateTime) new 
GenericLiteralVisitor(new GremlinAntlrToJava()).visitDateLiteral(ctx);
+            assertTrue(OffsetDateTime.now(UTC).toEpochSecond() - 
dt.toEpochSecond() < 1000);
         }
     }
 
diff --git 
a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/language/translator/GremlinTranslatorTest.java
 
b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/language/translator/GremlinTranslatorTest.java
index b16fbf057d..91955a13df 100644
--- 
a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/language/translator/GremlinTranslatorTest.java
+++ 
b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/language/translator/GremlinTranslatorTest.java
@@ -469,12 +469,12 @@ public class GremlinTranslatorTest {
                     {"g.with('x', datetime('2023-08-02T00:00:00Z'))",
                             null,
                             "g.with(string0, date0)",
-                            "g.With(\"x\", 
DateTimeOffset.FromUnixTimeMilliseconds(1690934400000))",
-                            "g.With(\"x\", time.UnixMilli(1690934400000))",
+                            "g.With(\"x\", 
DateTimeOffset.FromUnixTimeMilliseconds(1690934400000))", // todo: .net need 
update
+                            "g.With(\"x\", time.UnixMilli(1690934400000))", // 
todo: go need update
                             null,
-                            "g.with(\"x\", new Date(1690934400000))",
-                            "g.with_(\"x\", new Date(1690934400000))",
-                            "g.with_('x', 
datetime.datetime.utcfromtimestamp(1690934400000 / 1000.0))"},
+                            "g.with(\"x\", 
OffsetDateTime.parse(\"2023-08-02T00:00Z\"))",
+                            "g.with_(\"x\", new Date(1690934400000))",   // 
todo: js need update
+                            "g.with_('x', 
datetime.datetime.fromtimestamp(1690934400).astimezone(datetime.timezone.utc))"},
                     {"g.with('x', [x: 1])",
                             "g.with('x', [x:1])",
                             "g.with(string0, map0)",
diff --git 
a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/OrderTest.java
 
b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/OrderTest.java
index 01e630fc82..9d17501923 100644
--- 
a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/OrderTest.java
+++ 
b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/OrderTest.java
@@ -52,7 +52,6 @@ public class OrderTest {
     @RunWith(Parameterized.class)
     public static class OrderListTest {
 
-        // todo: re-enable date-related tests after implementing datetime
         private static final SimpleDateFormat formatter = new 
SimpleDateFormat("dd-MMM-yyyy", Locale.US);
 
         @Parameterized.Parameters(name = "{0}.sort({1}) = {2}")
@@ -62,10 +61,10 @@ public class OrderTest {
                     {Order.asc, Arrays.asList("b", "a", "c", "d"), 
Arrays.asList("a", "b", "c", "d")},
                     {Order.desc, Arrays.asList("b", "a", "c", "d"), 
Arrays.asList("d", "c", "b", "a")},
                     {Order.desc, Arrays.asList("c", "a", null, "d"), 
Arrays.asList("d", "c", "a", null)},
-//                    {Order.asc, Arrays.asList(formatter.parse("1-Jan-2018"), 
formatter.parse("1-Jan-2020"), formatter.parse("1-Jan-2008")),
-//                            Arrays.asList(formatter.parse("1-Jan-2008"), 
formatter.parse("1-Jan-2018"), formatter.parse("1-Jan-2020"))},
-//                    {Order.desc, 
Arrays.asList(formatter.parse("1-Jan-2018"), formatter.parse("1-Jan-2020"), 
formatter.parse("1-Jan-2008")),
-//                            Arrays.asList(formatter.parse("1-Jan-2020"), 
formatter.parse("1-Jan-2018"), formatter.parse("1-Jan-2008"))},
+                    {Order.asc, Arrays.asList(formatter.parse("1-Jan-2018"), 
formatter.parse("1-Jan-2020"), formatter.parse("1-Jan-2008")),
+                            Arrays.asList(formatter.parse("1-Jan-2008"), 
formatter.parse("1-Jan-2018"), formatter.parse("1-Jan-2020"))},
+                    {Order.desc, Arrays.asList(formatter.parse("1-Jan-2018"), 
formatter.parse("1-Jan-2020"), formatter.parse("1-Jan-2008")),
+                            Arrays.asList(formatter.parse("1-Jan-2020"), 
formatter.parse("1-Jan-2018"), formatter.parse("1-Jan-2008"))},
                     {Order.desc, Arrays.asList(100L, 1L, null, -1L, 0L), 
Arrays.asList(100L, 1L, 0L, -1L, null)},
                     {Order.desc, Arrays.asList(100L, 1L, -1L, 0L), 
Arrays.asList(100L, 1L, 0L, -1L)},
                     {Order.asc, Arrays.asList(100L, 1L, null, -1L, 0L), 
Arrays.asList(null, -1L, 0L, 1L, 100L)},
diff --git 
a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/AsDateStepTest.java
 
b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/AsDateStepTest.java
index 4d6e7b6377..68214eed88 100644
--- 
a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/AsDateStepTest.java
+++ 
b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/AsDateStepTest.java
@@ -24,10 +24,11 @@ import 
org.apache.tinkerpop.gremlin.process.traversal.step.StepTest;
 import org.junit.Test;
 
 import java.time.Instant;
-import java.time.ZonedDateTime;
+import java.time.LocalDateTime;
+import java.time.OffsetDateTime;
+import java.time.ZoneOffset;
 import java.util.Arrays;
 import java.util.Collections;
-import java.util.Date;
 import java.util.List;
 import java.util.UUID;
 
@@ -44,13 +45,12 @@ public class AsDateStepTest extends StepTest {
     @Test
     public void shouldParseDate() {
 
-        final Instant testInstant = ZonedDateTime.of(2023, 8, 2, 0, 0, 0, 0, 
UTC).toInstant();
-        final Date testDate = new Date(testInstant.getEpochSecond() * 1000);
+        final OffsetDateTime testDate = 
OffsetDateTime.of(LocalDateTime.of(2023, 8, 2, 0, 0, 0, 0), UTC);
 
-        assertEquals(new Date(1), __.__(1).asDate().next());
-        assertEquals(new Date(2), __.__(2.0).asDate().next());
-        assertEquals(new Date(3), __.__(3L).asDate().next());
-        assertEquals(testDate, __.__(testDate.getTime()).asDate().next());
+        assertEquals(OffsetDateTime.ofInstant(Instant.ofEpochMilli(1), 
ZoneOffset.UTC), __.__(1).asDate().next());
+        assertEquals(OffsetDateTime.ofInstant(Instant.ofEpochMilli(2), 
ZoneOffset.UTC), __.__(2.0).asDate().next());
+        assertEquals(OffsetDateTime.ofInstant(Instant.ofEpochMilli(3), 
ZoneOffset.UTC), __.__(3L).asDate().next());
+        assertEquals(testDate, 
__.__(testDate.toInstant().toEpochMilli()).asDate().next());
 
         assertEquals(testDate, __.__("2023-08-02T00:00:00Z").asDate().next());
         assertEquals(testDate, __.__(testDate).asDate().next());
diff --git 
a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/DateAddStepTest.java
 
b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/DateAddStepTest.java
index f7bb2efbeb..135736722f 100644
--- 
a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/DateAddStepTest.java
+++ 
b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/DateAddStepTest.java
@@ -24,11 +24,12 @@ import 
org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__;
 import org.apache.tinkerpop.gremlin.process.traversal.step.StepTest;
 import org.junit.Test;
 
-import java.util.Calendar;
+import java.time.Duration;
+import java.time.OffsetDateTime;
 import java.util.Collections;
-import java.util.Date;
 import java.util.List;
 
+import static java.time.ZoneOffset.UTC;
 import static org.junit.Assert.assertEquals;
 
 public class DateAddStepTest extends StepTest {
@@ -40,60 +41,40 @@ public class DateAddStepTest extends StepTest {
 
     @Test
     public void shouldAddHours() {
-        final Date now = new Date();
-
-        final Calendar cal = Calendar.getInstance();
-        cal.setTime(now);
-        cal.add(Calendar.HOUR_OF_DAY, 2);
-        final Date expected = cal.getTime();
+        final OffsetDateTime now = OffsetDateTime.now(UTC);
+        final OffsetDateTime expected = now.plus(Duration.ofHours(2));
 
         assertEquals(expected, __.__(now).dateAdd(DT.hour, 2).next());
     }
 
     @Test
     public void shouldAddNegativeHours() {
-        final Date now = new Date();
-
-        final Calendar cal = Calendar.getInstance();
-        cal.setTime(now);
-        cal.add(Calendar.HOUR_OF_DAY, -3);
-        final Date expected = cal.getTime();
+        final OffsetDateTime now = OffsetDateTime.now(UTC);
+        final OffsetDateTime expected = now.plus(Duration.ofHours(-3));
 
         assertEquals(expected, __.__(now).dateAdd(DT.hour, -3).next());
     }
 
     @Test
     public void shouldAddMinutes() {
-        final Date now = new Date();
-
-        final Calendar cal = Calendar.getInstance();
-        cal.setTime(now);
-        cal.add(Calendar.MINUTE, 5);
-        final Date expected = cal.getTime();
+        final OffsetDateTime now = OffsetDateTime.now(UTC);
+        final OffsetDateTime expected = now.plus(Duration.ofMinutes(5));
 
         assertEquals(expected, __.__(now).dateAdd(DT.minute, 5).next());
     }
 
     @Test
     public void shouldAddSeconds() {
-        final Date now = new Date();
-
-        final Calendar cal = Calendar.getInstance();
-        cal.setTime(now);
-        cal.add(Calendar.SECOND, 15);
-        final Date expected = cal.getTime();
+        final OffsetDateTime now = OffsetDateTime.now(UTC);
+        final OffsetDateTime expected = now.plus(Duration.ofSeconds(15));
 
         assertEquals(expected, __.__(now).dateAdd(DT.second, 15).next());
     }
 
     @Test
     public void shouldAddDays() {
-        final Date now = new Date();
-
-        final Calendar cal = Calendar.getInstance();
-        cal.setTime(now);
-        cal.add(Calendar.DAY_OF_MONTH, 50);
-        final Date expected = cal.getTime();
+        final OffsetDateTime now = OffsetDateTime.now(UTC);
+        final OffsetDateTime expected = now.plus(Duration.ofDays(50));
 
         assertEquals(expected, __.__(now).dateAdd(DT.day, 50).next());
     }
diff --git 
a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/DateDiffStepTest.java
 
b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/DateDiffStepTest.java
index 0cffa601ba..8ff2effdee 100644
--- 
a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/DateDiffStepTest.java
+++ 
b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/DateDiffStepTest.java
@@ -23,11 +23,10 @@ import 
org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__;
 import org.apache.tinkerpop.gremlin.process.traversal.step.StepTest;
 import org.junit.Test;
 
-import java.util.Calendar;
+import java.time.Duration;
+import java.time.OffsetDateTime;
 import java.util.Collections;
-import java.util.Date;
 import java.util.List;
-import java.util.TimeZone;
 
 import static java.time.ZoneOffset.UTC;
 import static org.junit.Assert.assertEquals;
@@ -36,64 +35,49 @@ public class DateDiffStepTest extends StepTest {
 
     @Override
     protected List<Traversal> getTraversals() {
-        return Collections.singletonList(__.dateDiff(new 
Date(1690934420000L)));
+        return 
Collections.singletonList(__.dateDiff(OffsetDateTime.parse("2023-08-02T00:00:20Z")));
     }
 
     @Test
     public void shouldHandlePositiveValues() {
-        final Date now = new Date();
-
-        final Calendar cal = Calendar.getInstance();
-        cal.setTime(now);
-        cal.setTimeZone(TimeZone.getTimeZone(UTC));
-        cal.add(Calendar.DAY_OF_MONTH, 7);
-        final Date other = cal.getTime();
+        final OffsetDateTime now = OffsetDateTime.now(UTC);
+        final OffsetDateTime other = now.plus(Duration.ofDays(7));
 
         assertEquals(604800L, (long) __.__(other).dateDiff(now).next());
     }
 
     @Test
     public void shouldHandleNegativeValues() {
-        final Date now = new Date();
-
-        final Calendar cal = Calendar.getInstance();
-        cal.setTime(now);
-        cal.setTimeZone(TimeZone.getTimeZone(UTC));
-        cal.add(Calendar.DAY_OF_MONTH, 7);
-        final Date other = cal.getTime();
+        final OffsetDateTime now = OffsetDateTime.now(UTC);
+        final OffsetDateTime other = now.plus(Duration.ofDays(7));
 
         assertEquals(-604800L, (long) __.__(now).dateDiff(other).next());
     }
 
     @Test
     public void shouldHandleTraversalParam() {
-        final Date now = new Date();
-
-        final Calendar cal = Calendar.getInstance();
-        cal.setTime(now);
-        cal.setTimeZone(TimeZone.getTimeZone(UTC));
-        cal.add(Calendar.DAY_OF_MONTH, 7);
-        final Date other = cal.getTime();
+        final OffsetDateTime now = OffsetDateTime.now(UTC);
+        final OffsetDateTime other = now.plus(Duration.ofDays(7));
 
         assertEquals(-604800L, (long) 
__.__(now).dateDiff(__.constant(other)).next());
     }
 
     @Test
     public void shouldHandleNullTraversalParam() {
-        final Date now = new Date();
+        final OffsetDateTime now = OffsetDateTime.now(UTC);
 
-        assertEquals(now.getTime() / 1000, (long) 
__.__(now).dateDiff(__.constant(null)).next());
+        assertEquals(now.toEpochSecond(), (long) 
__.__(now).dateDiff(__.constant(null)).next());
     }
 
     @Test
     public void shouldHandleNullDate() {
-        final Date now = new Date();
+        final OffsetDateTime now = OffsetDateTime.now(UTC);
 
-        assertEquals(now.getTime() / 1000, (long) __.__(now).dateDiff((Date) 
null).next());
+        assertEquals(now.toEpochSecond(), (long) 
__.__(now).dateDiff((OffsetDateTime) null).next());
     }
 
     @Test(expected = IllegalArgumentException.class)
     public void shouldThrowWhenInputIsNotDate() {
-        __.__("2023-08-23T00:00:00Z").dateDiff(new Date()).next();
+        __.__("2023-08-23T00:00:00Z").dateDiff(OffsetDateTime.now(UTC)).next();
     }
 }
diff --git 
a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/util/DatetimeHelperTest.java
 
b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/util/DatetimeHelperTest.java
index 72ea3f1558..a3a1372903 100644
--- 
a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/util/DatetimeHelperTest.java
+++ 
b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/util/DatetimeHelperTest.java
@@ -24,11 +24,11 @@ import org.junit.runner.RunWith;
 import org.junit.runners.Parameterized;
 
 import java.time.Instant;
-import java.time.ZoneId;
+import java.time.LocalDateTime;
+import java.time.OffsetDateTime;
 import java.time.ZoneOffset;
 import java.time.ZonedDateTime;
 import java.util.Arrays;
-import java.util.Date;
 
 import static java.time.ZoneOffset.UTC;
 import static org.junit.Assert.assertEquals;
@@ -43,35 +43,35 @@ public class DatetimeHelperTest {
         public String d;
 
         @Parameterized.Parameter(value = 1)
-        public Date expected;
+        public OffsetDateTime expected;
 
         @Parameterized.Parameters(name = "{0}")
         public static Iterable<Object[]> generateTestParameters() {
             return Arrays.asList(new Object[][]{
-                    {"2018-03-22T00:35:44.741Z", 
Date.from(ZonedDateTime.of(2018, 03, 22, 00, 35, 44, 741000000, 
UTC).toInstant())},
-                    {"2018-03-22T00:35:44.741-0000", 
Date.from(ZonedDateTime.of(2018, 03, 22, 00, 35, 44, 741000000, 
UTC).toInstant())},
-                    {"2018-03-22T00:35:44.741+0000", 
Date.from(ZonedDateTime.of(2018, 03, 22, 00, 35, 44, 741000000, 
UTC).toInstant())},
-                    {"2018-03-22T00:35:44.741+00:00", 
Date.from(ZonedDateTime.of(2018, 03, 22, 00, 35, 44, 741000000, 
UTC).toInstant())},
-                    {"2018-03-22T00:35:44.741+000000", 
Date.from(ZonedDateTime.of(2018, 03, 22, 00, 35, 44, 741000000, 
UTC).toInstant())},
-                    {"2018-03-22T00:35:44.741+00:00:00", 
Date.from(ZonedDateTime.of(2018, 03, 22, 00, 35, 44, 741000000, 
UTC).toInstant())},
-                    {"2018-03-22T00:35:44.741-0300", 
Date.from(ZonedDateTime.of(2018, 03, 22, 00, 35, 44, 741000000, 
ZoneOffset.ofHours(-3)).toInstant())},
-                    {"2018-03-22T00:35:44.741+1600", 
Date.from(ZonedDateTime.of(2018, 03, 22, 00, 35, 44, 741000000, 
ZoneOffset.ofHours(16)).toInstant())},
-                    {"2018-03-22T00:35:44.741+16:00", 
Date.from(ZonedDateTime.of(2018, 03, 22, 00, 35, 44, 741000000, 
ZoneOffset.ofHours(16)).toInstant())},
-                    {"2018-03-22T00:35:44.741+160000", 
Date.from(ZonedDateTime.of(2018, 03, 22, 00, 35, 44, 741000000, 
ZoneOffset.ofHours(16)).toInstant())},
-                    {"2018-03-22T00:35:44.741+16:00:00", 
Date.from(ZonedDateTime.of(2018, 03, 22, 00, 35, 44, 741000000, 
ZoneOffset.ofHours(16)).toInstant())},
-                    {"2018-03-22T00:35:44.741+1659", 
Date.from(ZonedDateTime.of(2018, 03, 22, 00, 35, 44, 741000000, 
ZoneOffset.ofHoursMinutes(16, 59)).toInstant())},
-                    {"2018-03-22T00:35:44.741+16:59", 
Date.from(ZonedDateTime.of(2018, 03, 22, 00, 35, 44, 741000000, 
ZoneOffset.ofHoursMinutes(16, 59)).toInstant())},
-                    {"2018-03-22T00:35:44.741+165900", 
Date.from(ZonedDateTime.of(2018, 03, 22, 00, 35, 44, 741000000, 
ZoneOffset.ofHoursMinutes(16, 59)).toInstant())},
-                    {"2018-03-22T00:35:44.741+16:59:00", 
Date.from(ZonedDateTime.of(2018, 03, 22, 00, 35, 44, 741000000, 
ZoneOffset.ofHoursMinutes(16, 59)).toInstant())},
-                    {"2018-03-22T00:35:44.741+165930", 
Date.from(ZonedDateTime.of(2018, 03, 22, 00, 35, 44, 741000000, 
ZoneOffset.ofHoursMinutesSeconds(16, 59, 30)).toInstant())},
-                    {"2018-03-22T00:35:44.741+16:59:30", 
Date.from(ZonedDateTime.of(2018, 03, 22, 00, 35, 44, 741000000, 
ZoneOffset.ofHoursMinutesSeconds(16, 59, 30)).toInstant())},
-                    {"2018-03-22T00:35:44.741", 
Date.from(ZonedDateTime.of(2018, 03, 22, 00, 35, 44, 741000000, 
UTC).toInstant())},
-                    {"2018-03-22T00:35:44Z", Date.from(ZonedDateTime.of(2018, 
03, 22, 00, 35, 44, 0, UTC).toInstant())},
-                    {"2018-03-22T00:35:44", Date.from(ZonedDateTime.of(2018, 
03, 22, 00, 35, 44, 0, UTC).toInstant())},
-                    {"2018-03-22", Date.from(ZonedDateTime.of(2018, 03, 22, 0, 
0, 0, 0, UTC).toInstant())},
-                    {"1018-03-22", Date.from(ZonedDateTime.of(1018, 03, 22, 0, 
0, 0, 0, UTC).toInstant())},
-                    {"9018-03-22", Date.from(ZonedDateTime.of(9018, 03, 22, 0, 
0, 0, 0, UTC).toInstant())},
-                    {"1000-001", Date.from(ZonedDateTime.of(1000, 1, 1, 0, 0, 
0, 0, UTC).toInstant())},
+                    {"2018-03-22T00:35:44.741Z", 
OffsetDateTime.of(LocalDateTime.of(2018, 03, 22, 00, 35, 44, 741000000), UTC)},
+                    {"2018-03-22T00:35:44.741-0000", 
OffsetDateTime.of(LocalDateTime.of(2018, 03, 22, 00, 35, 44, 741000000), UTC)},
+                    {"2018-03-22T00:35:44.741+0000", 
OffsetDateTime.of(LocalDateTime.of(2018, 03, 22, 00, 35, 44, 741000000), UTC)},
+                    {"2018-03-22T00:35:44.741+00:00", 
OffsetDateTime.of(LocalDateTime.of(2018, 03, 22, 00, 35, 44, 741000000), UTC)},
+                    {"2018-03-22T00:35:44.741+000000", 
OffsetDateTime.of(LocalDateTime.of(2018, 03, 22, 00, 35, 44, 741000000), UTC)},
+                    {"2018-03-22T00:35:44.741+00:00:00", 
OffsetDateTime.of(LocalDateTime.of(2018, 03, 22, 00, 35, 44, 741000000), UTC)},
+                    {"2018-03-22T00:35:44.741-0300", 
OffsetDateTime.of(LocalDateTime.of(2018, 03, 22, 00, 35, 44, 741000000), 
ZoneOffset.ofHours(-3))},
+                    {"2018-03-22T00:35:44.741+1600", 
OffsetDateTime.of(LocalDateTime.of(2018, 03, 22, 00, 35, 44, 741000000), 
ZoneOffset.ofHours(16))},
+                    {"2018-03-22T00:35:44.741+16:00", 
OffsetDateTime.of(LocalDateTime.of(2018, 03, 22, 00, 35, 44, 741000000), 
ZoneOffset.ofHours(16))},
+                    {"2018-03-22T00:35:44.741+160000", 
OffsetDateTime.of(LocalDateTime.of(2018, 03, 22, 00, 35, 44, 741000000), 
ZoneOffset.ofHours(16))},
+                    {"2018-03-22T00:35:44.741+16:00:00", 
OffsetDateTime.of(LocalDateTime.of(2018, 03, 22, 00, 35, 44, 741000000), 
ZoneOffset.ofHours(16))},
+                    {"2018-03-22T00:35:44.741+1659", 
OffsetDateTime.of(LocalDateTime.of(2018, 03, 22, 00, 35, 44, 741000000), 
ZoneOffset.ofHoursMinutes(16, 59))},
+                    {"2018-03-22T00:35:44.741+16:59", 
OffsetDateTime.of(LocalDateTime.of(2018, 03, 22, 00, 35, 44, 741000000), 
ZoneOffset.ofHoursMinutes(16, 59))},
+                    {"2018-03-22T00:35:44.741+165900", 
OffsetDateTime.of(LocalDateTime.of(2018, 03, 22, 00, 35, 44, 741000000), 
ZoneOffset.ofHoursMinutes(16, 59))},
+                    {"2018-03-22T00:35:44.741+16:59:00", 
OffsetDateTime.of(LocalDateTime.of(2018, 03, 22, 00, 35, 44, 741000000), 
ZoneOffset.ofHoursMinutes(16, 59))},
+                    {"2018-03-22T00:35:44.741+165930", 
OffsetDateTime.of(LocalDateTime.of(2018, 03, 22, 00, 35, 44, 741000000), 
ZoneOffset.ofHoursMinutesSeconds(16, 59, 30))},
+                    {"2018-03-22T00:35:44.741+16:59:30", 
OffsetDateTime.of(LocalDateTime.of(2018, 03, 22, 00, 35, 44, 741000000), 
ZoneOffset.ofHoursMinutesSeconds(16, 59, 30))},
+                    {"2018-03-22T00:35:44.741", 
OffsetDateTime.of(LocalDateTime.of(2018, 03, 22, 00, 35, 44, 741000000), UTC)},
+                    {"2018-03-22T00:35:44Z", 
OffsetDateTime.of(LocalDateTime.of(2018, 03, 22, 00, 35, 44, 0), UTC)},
+                    {"2018-03-22T00:35:44", 
OffsetDateTime.of(LocalDateTime.of(2018, 03, 22, 00, 35, 44, 0), UTC)},
+                    {"2018-03-22", OffsetDateTime.of(LocalDateTime.of(2018, 
03, 22, 0, 0, 0, 0), UTC)},
+                    {"1018-03-22", OffsetDateTime.of(LocalDateTime.of(1018, 
03, 22, 0, 0, 0, 0), UTC)},
+                    {"9018-03-22", OffsetDateTime.of(LocalDateTime.of(9018, 
03, 22, 0, 0, 0, 0), UTC)},
+                    {"1000-001", OffsetDateTime.of(LocalDateTime.of(1000, 1, 
1, 0, 0, 0, 0), UTC)},
             });
         }
 
diff --git a/gremlin-python/src/main/python/gremlin_python/statics.py 
b/gremlin-python/src/main/python/gremlin_python/statics.py
index fbd5422e3f..c3b9cd8d5b 100644
--- a/gremlin-python/src/main/python/gremlin_python/statics.py
+++ b/gremlin-python/src/main/python/gremlin_python/statics.py
@@ -45,14 +45,6 @@ SetType = set
 ByteBufferType = bytes
 
 
-class timestamp(float):
-    """
-    In Python a timestamp is simply a float. This dummy class (similar to 
long), allows users to wrap a float
-    in a GLV script to make sure the value is serialized as a Gremlin 
timestamp.
-    """
-    pass
-
-
 class SingleByte(int):
     """
     Provides a way to pass a single byte via Gremlin.
diff --git 
a/gremlin-python/src/main/python/gremlin_python/structure/io/graphbinaryV4.py 
b/gremlin-python/src/main/python/gremlin_python/structure/io/graphbinaryV4.py
index 095d7debe4..3cf8f53a3e 100644
--- 
a/gremlin-python/src/main/python/gremlin_python/structure/io/graphbinaryV4.py
+++ 
b/gremlin-python/src/main/python/gremlin_python/structure/io/graphbinaryV4.py
@@ -17,14 +17,13 @@ specific language governing permissions and limitations
 under the License.
 """
 import calendar
-import datetime
 import io
 import logging
 import math
 import struct
 import uuid
 from collections import OrderedDict
-from datetime import timedelta
+from datetime import datetime, timedelta, timezone
 from struct import pack, unpack
 
 from aenum import Enum
@@ -48,7 +47,7 @@ class DataType(Enum):
     int = 0x01
     long = 0x02
     string = 0x03
-    # date = 0x04
+    datetime = 0x04
     double = 0x07
     float = 0x08
     list = 0x09
@@ -74,7 +73,6 @@ class DataType(Enum):
     char = 0x80
     duration = 0x81
     marker = 0xfd
-    offsetdatetime = 0x88         # todo: will need to update to datetime
     custom = 0x00                 # todo
 
 
@@ -356,6 +354,45 @@ class BigDecimalIO(_GraphBinaryTypeIO):
         return cls.is_null(buff, reader, lambda b, r: cls._read(b), nullable)
 
 
+class DateTimeIO(_GraphBinaryTypeIO):
+
+    python_type = datetime
+    graphbinary_type = DataType.datetime
+
+    @classmethod
+    def dictify(cls, obj, writer, to_extend, as_value=False, nullable=True):
+        if obj.tzinfo is None:
+            raise AttributeError("Timezone information is required when 
constructing datetime")
+        cls.prefix_bytes(cls.graphbinary_type, as_value, nullable, to_extend)
+        IntIO.dictify(obj.year, writer, to_extend, True, False)
+        ByteIO.dictify(obj.month, writer, to_extend, True, False)
+        ByteIO.dictify(obj.day, writer, to_extend, True, False)
+        # construct time of day in nanoseconds
+        h = obj.time().hour
+        m = obj.time().minute
+        s = obj.time().second
+        ms = obj.time().microsecond
+        ns = round((h*60*60*1e9) + (m*60*1e9) + (s*1e9) + (ms*1e3))
+        LongIO.dictify(ns, writer, to_extend, True, False)
+        os = round(obj.utcoffset().total_seconds())
+        IntIO.dictify(os, writer, to_extend, True, False)
+        return to_extend
+
+    @classmethod
+    def objectify(cls, buff, reader, nullable=True):
+        return cls.is_null(buff, reader, cls._read_dt, nullable)
+
+    @classmethod
+    def _read_dt(cls, b, r):
+        year = r.to_object(b, DataType.int, False)
+        month = r.to_object(b, DataType.byte, False)
+        day = r.to_object(b, DataType.byte, False)
+        ns = r.to_object(b, DataType.long, False)
+        offset = r.to_object(b, DataType.int, False)
+        tz = timezone(timedelta(seconds=offset))
+        return datetime(year, month, day, tzinfo=tz) + 
timedelta(microseconds=ns/1000)
+
+
 class CharIO(_GraphBinaryTypeIO):
     python_type = SingleChar
     graphbinary_type = DataType.char
diff --git a/gremlin-python/src/main/python/radish/feature_steps.py 
b/gremlin-python/src/main/python/radish/feature_steps.py
index 53bdd0e240..6ba00d7d78 100644
--- a/gremlin-python/src/main/python/radish/feature_steps.py
+++ b/gremlin-python/src/main/python/radish/feature_steps.py
@@ -231,7 +231,7 @@ def _convert(val, ctx):
         return val[4:-1]
     elif isinstance(val, str) and re.match(r"^dt\[.*\]$", val):  # parse 
datetime
         # python 3.8 can handle only subset of ISO 8601 dates
-        return datetime.fromisoformat(val[3:-1].replace('Z', ''))
+        return datetime.fromisoformat(val[3:-1].replace('Z', '+00:00'))
     elif isinstance(val, str) and re.match(r"^d\[NaN\]$", val):  # parse nan
         return float("nan")
     elif isinstance(val, str) and re.match(r"^d\[Infinity\]$", val):  # parse 
+inf
diff --git a/gremlin-python/src/main/python/radish/gremlin.py 
b/gremlin-python/src/main/python/radish/gremlin.py
index 448717fee9..04ef5e0e6b 100644
--- a/gremlin-python/src/main/python/radish/gremlin.py
+++ b/gremlin-python/src/main/python/radish/gremlin.py
@@ -522,6 +522,13 @@ world.gremlins = {
     
'g_addVXpersonX_propertyXname_markoX_propertyXfriendWeight_null_acl_nullX': 
[(lambda g:g.add_v('person').property('name', 'marko').property('friendWeight', 
None, 'acl', None)), (lambda g:g.V().has('person', 'name', 
'marko').has('friendWeight', None)), (lambda g:g.V().has('person', 'name', 
'marko').properties('friendWeight').has('acl', None)), (lambda 
g:g.V().has('person', 'name', 'marko').properties('friendWeight').count())], 
     
'g_V_hasXperson_name_aliceX_propertyXsingle_age_unionXage_constantX1XX_sumX': 
[(lambda g:g.add_v('person').property('name', 
'alice').property(Cardinality.single, 'age', 50)), (lambda 
g:g.V().has('person', 'name', 'alice').property('age', 
__.union(__.values('age'), __.constant(1)).sum_())), (lambda 
g:g.V().has('person', 'age', 50)), (lambda g:g.V().has('person', 'age', 51))], 
     
'g_V_limitX3X_addVXsoftwareX_aggregateXa1X_byXlabelX_aggregateXa2X_byXlabelX_capXa1_a2X_selectXa_bX_byXunfoldX_foldX':
 [(lambda g:g.add_v('person').property('name', 'marko').property('age', 
29).as_('marko').add_v('person').property('name', 'vadas').property('age', 
27).as_('vadas').add_v('software').property('name', 'lop').property('lang', 
'java').as_('lop').add_v('person').property('name', 'josh').property('age', 
32).as_('josh').add_v('software').property('name', 'ripple').property(' [...]
+    'g_injectXstrX_asDate': [(lambda 
g:g.inject('2023-08-02T00:00:00Z').as_date())], 
+    'g_injectX1694017707000X_asDate': [(lambda 
g:g.inject(long(1694017707000)).as_date())], 
+    'g_injectX1694017708000LX_asDate': [(lambda g, 
xx1=None:g.inject(xx1).as_date())], 
+    'g_injectX1694017709000dX_asDate': [(lambda g, 
xx1=None:g.inject(xx1).as_date())], 
+    'g_injectX1_2X_asDate': [(lambda g, xx1=None:g.inject(xx1).as_date())], 
+    'g_injectXnullX_asDate': [(lambda g:g.inject(None).as_date())], 
+    'g_injectXinvalidstrX_asDate': [(lambda g:g.inject('This String is not an 
ISO 8601 Date').as_date())], 
     'g_injectX1_2X_asString': [(lambda g, xx1=None,xx2=None:g.inject(xx1, 
xx2).as_string())], 
     'g_injectX1_2X_asStringXlocalX': [(lambda g, 
xx1=None,xx2=None:g.inject(xx1, xx2).as_string(Scope.local))], 
     'g_injectXlist_1_2X_asStringXlocalX': [(lambda g, 
xx1=None:g.inject(xx1).as_string(Scope.local))], 
@@ -628,9 +635,15 @@ world.gremlins = {
     'g_V_order_byXnoX_count': [(lambda g:g.V().order().by('no').count())], 
     'g_V_group_byXlabelX_count': [(lambda 
g:g.V().group().by(T.label).count())], 
     'g_V_group_byXlabelX_countXlocalX': [(lambda 
g:g.V().group().by(T.label).count(Scope.local))], 
-    'g_injectXdatetimeXstr1XX_dateDiffXdatetimeXstr2XX': [(lambda 
g:g.inject(datetime.datetime.utcfromtimestamp(1690934400000 / 
1000.0)).date_diff(datetime.datetime.utcfromtimestamp(1691539200000 / 
1000.0)))], 
-    'g_injectXdatetimeXstr1XX_dateDiffXconstantXdatetimeXstr2XXX': [(lambda 
g:g.inject(datetime.datetime.utcfromtimestamp(1691452800000 / 
1000.0)).date_diff(__.constant(datetime.datetime.utcfromtimestamp(1690848000000 
/ 1000.0))))], 
-    'g_injectXdatetimeXstr1XX_dateDiffXinjectXdatetimeXstr2XXX': [(lambda 
g:g.inject(datetime.datetime.utcfromtimestamp(1691452800000 / 
1000.0)).date_diff(__.inject(datetime.datetime.utcfromtimestamp(1696982400000 / 
1000.0))))], 
+    'g_injectXdatetimeXstrXX_dateAddXDT_hour_2X': [(lambda 
g:g.inject(datetime.datetime.fromtimestamp(1690934400).astimezone(datetime.timezone.utc)).date_add(DT.hour,
 2))], 
+    'g_injectXdatetimeXstrXX_dateAddXhour_2X': [(lambda 
g:g.inject(datetime.datetime.fromtimestamp(1690934400).astimezone(datetime.timezone.utc)).date_add(DT.hour,
 2))], 
+    'g_injectXdatetimeXstrXX_dateAddXhour_1X': [(lambda 
g:g.inject(datetime.datetime.fromtimestamp(1690934400).astimezone(datetime.timezone.utc)).date_add(DT.hour,
 -1))], 
+    'g_injectXdatetimeXstrXX_dateAddXminute_10X': [(lambda 
g:g.inject(datetime.datetime.fromtimestamp(1690934400).astimezone(datetime.timezone.utc)).date_add(DT.minute,
 10))], 
+    'g_injectXdatetimeXstrXX_dateAddXsecond_20X': [(lambda 
g:g.inject(datetime.datetime.fromtimestamp(1690934400).astimezone(datetime.timezone.utc)).date_add(DT.second,
 20))], 
+    'g_injectXdatetimeXstrXX_dateAddXday_11X': [(lambda 
g:g.inject(datetime.datetime.fromtimestamp(1693958400).astimezone(datetime.timezone.utc)).date_add(DT.day,
 11))], 
+    'g_injectXdatetimeXstr1XX_dateDiffXdatetimeXstr2XX': [(lambda 
g:g.inject(datetime.datetime.fromtimestamp(1690934400).astimezone(datetime.timezone.utc)).date_diff(datetime.datetime.fromtimestamp(1691539200).astimezone(datetime.timezone.utc)))],
 
+    'g_injectXdatetimeXstr1XX_dateDiffXconstantXdatetimeXstr2XXX': [(lambda 
g:g.inject(datetime.datetime.fromtimestamp(1691452800).astimezone(datetime.timezone.utc)).date_diff(__.constant(datetime.datetime.fromtimestamp(1690848000).astimezone(datetime.timezone.utc))))],
 
+    'g_injectXdatetimeXstr1XX_dateDiffXinjectXdatetimeXstr2XXX': [(lambda 
g:g.inject(datetime.datetime.fromtimestamp(1691452800).astimezone(datetime.timezone.utc)).date_diff(__.inject(datetime.datetime.fromtimestamp(1696982400).astimezone(datetime.timezone.utc))))],
 
     'g_injectXnullX_differenceXinjectX1XX': [(lambda 
g:g.inject(None).difference(__.inject(1)))], 
     'g_V_valuesXnameX_differenceXV_foldX': [(lambda 
g:g.V().values('name').difference(__.V().fold()))], 
     'g_V_fold_differenceXconstantXnullXX': [(lambda 
g:g.V().fold().difference(__.constant(None)))], 
diff --git 
a/gremlin-python/src/main/python/tests/structure/io/test_functionalityio.py 
b/gremlin-python/src/main/python/tests/structure/io/test_functionalityio.py
index 5f8c2de196..8dbd0a5af5 100644
--- a/gremlin-python/src/main/python/tests/structure/io/test_functionalityio.py
+++ b/gremlin-python/src/main/python/tests/structure/io/test_functionalityio.py
@@ -17,10 +17,10 @@ specific language governing permissions and limitations
 under the License.
 '''
 
-import datetime
 import uuid
-
 import pytest
+
+from datetime import datetime, timedelta, timezone
 from gremlin_python.driver.serializer import GraphBinarySerializersV4
 from gremlin_python.process.anonymous_traversal import traversal
 from gremlin_python.statics import *
@@ -81,30 +81,16 @@ def test_vertex_vertex_properties(remote_connection_crew):
     assert vertex.properties[1].properties[1].value == 2000
 
 
[email protected](reason="timestamp replaced by datetime in GraphBinaryV4, 
revisit to update after implementation")
-def test_timestamp(remote_connection):
-    g = traversal().with_(remote_connection)
-    ts = timestamp(1481750076295 / 1000)
-    resp = g.add_v('test_vertex').property('ts', ts)
-    resp = resp.to_list()
-    vid = resp[0].id
-    try:
-        ts_prop = g.V(vid).properties('ts').to_list()[0]
-        assert isinstance(ts_prop.value, timestamp)
-        assert ts_prop.value == ts
-    finally:
-        g.V(vid).drop().iterate()
-
-
[email protected](reason="timestamp replaced by datetime in GraphBinaryV4, 
revisit to update after implementation")
 def test_datetime(remote_connection):
     g = traversal().with_(remote_connection)
-    dt = datetime.datetime.utcfromtimestamp(1481750076295 / 1000)
+    tz = timezone(timedelta(seconds=36000))
+    ms = 12345678912
+    dt = datetime(2022, 5, 20, tzinfo=tz) + timedelta(microseconds=ms)
     resp = g.add_v('test_vertex').property('dt', dt).to_list()
     vid = resp[0].id
     try:
         dt_prop = g.V(vid).properties('dt').to_list()[0]
-        assert isinstance(dt_prop.value, datetime.datetime)
+        assert isinstance(dt_prop.value, datetime)
         assert dt_prop.value == dt
     finally:
         g.V(vid).drop().iterate()
@@ -209,7 +195,7 @@ def test_odd_bits(remote_connection):
     finally:
         g.V(vid).drop().iterate()
 
-    dur = datetime.timedelta(seconds=1000, microseconds=1000)
+    dur = timedelta(seconds=1000, microseconds=1000)
     resp = g.add_v('test_vertex').property('dur', dur).to_list()
     vid = resp[0].id
     try:
diff --git 
a/gremlin-python/src/main/python/tests/structure/io/test_graphbinaryV4.py 
b/gremlin-python/src/main/python/tests/structure/io/test_graphbinaryV4.py
index 0702895ac4..486773fa0d 100644
--- a/gremlin-python/src/main/python/tests/structure/io/test_graphbinaryV4.py
+++ b/gremlin-python/src/main/python/tests/structure/io/test_graphbinaryV4.py
@@ -17,11 +17,11 @@ specific language governing permissions and limitations
 under the License.
 """
 
-import datetime
 import uuid
 import math
 
-from gremlin_python.statics import timestamp, long, bigint, BigDecimal, 
SingleByte, SingleChar, ByteBufferType
+from datetime import datetime, timedelta, timezone
+from gremlin_python.statics import long, bigint, BigDecimal, SingleByte, 
SingleChar, ByteBufferType
 from gremlin_python.structure.graph import Vertex, Edge, Property, 
VertexProperty, Path
 from gremlin_python.structure.io.graphbinaryV4 import GraphBinaryWriter, 
GraphBinaryReader
 from gremlin_python.process.traversal import Direction
@@ -79,8 +79,25 @@ class TestGraphBinaryV4(object):
         assert x.scale == output.scale
         assert x.unscaled_value == output.unscaled_value
 
-    def test_timestamp(self):
-        x = timestamp(1481750076295 / 1000)
+    def test_datetime(self):
+        tz = timezone(timedelta(seconds=36000))
+        ms = 12345678912
+        x = datetime(2022, 5, 20, tzinfo=tz) + timedelta(microseconds=ms)
+        output = 
self.graphbinary_reader.read_object(self.graphbinary_writer.write_object(x))
+        assert x == output
+
+    def test_datetime_format(self):
+        x = datetime.strptime('2022-05-20T03:25:45.678912Z', 
'%Y-%m-%dT%H:%M:%S.%f%z')
+        output = 
self.graphbinary_reader.read_object(self.graphbinary_writer.write_object(x))
+        assert x == output
+
+    def test_datetime_local(self):
+        x = datetime.now().astimezone()
+        output = 
self.graphbinary_reader.read_object(self.graphbinary_writer.write_object(x))
+        assert x == output
+
+    def test_datetime_epoch(self):
+        x = datetime.fromtimestamp(1690934400).astimezone(timezone.utc)
         output = 
self.graphbinary_reader.read_object(self.graphbinary_writer.write_object(x))
         assert x == output
 
@@ -202,7 +219,7 @@ class TestGraphBinaryV4(object):
         assert x == output
 
     def test_duration(self):
-        x = datetime.timedelta(seconds=1000, microseconds=1000)
+        x = timedelta(seconds=1000, microseconds=1000)
         output = 
self.graphbinary_reader.read_object(self.graphbinary_writer.write_object(x))
         assert x == output
 
diff --git 
a/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/test/features/map/AsDate.feature
 
b/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/test/features/map/AsDate.feature
index 122be0dff7..23f46ee70c 100644
--- 
a/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/test/features/map/AsDate.feature
+++ 
b/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/test/features/map/AsDate.feature
@@ -18,84 +18,84 @@
 # todo: re-enable after datetime is implemented
 @StepClassMap @StepAsDate
 Feature: Step - asDate()
-#
-#  @GraphComputerVerificationInjectionNotSupported
-#  Scenario: g_injectXstrX_asDate
-#    Given the empty graph
-#    And the traversal of
-#      """
-#      g.inject("2023-08-02T00:00:00Z").asDate()
-#      """
-#    When iterated to list
-#    Then the result should be unordered
-#      | result |
-#      | dt[2023-08-02T00:00:00Z] |
-#
-#  @GraphComputerVerificationInjectionNotSupported
-#  Scenario: g_injectX1694017707000X_asDate
-#    Given the empty graph
-#    And the traversal of
-#      """
-#      g.inject(1694017707000).asDate()
-#      """
-#    When iterated to list
-#    Then the result should be unordered
-#      | result |
-#      | dt[2023-09-06T16:28:27Z] |
-#
-#  @GraphComputerVerificationInjectionNotSupported
-#  Scenario: g_injectX1694017708000LX_asDate
-#    Given the empty graph
-#    And using the parameter xx1 defined as "d[1694017708000].l"
-#    And the traversal of
-#      """
-#      g.inject(xx1).asDate()
-#      """
-#    When iterated to list
-#    Then the result should be unordered
-#      | result |
-#      | dt[2023-09-06T16:28:28Z] |
-#
-#  @GraphComputerVerificationInjectionNotSupported
-#  Scenario: g_injectX1694017709000dX_asDate
-#    Given the empty graph
-#    And using the parameter xx1 defined as "d[1694017709000.1].d"
-#    And the traversal of
-#      """
-#      g.inject(xx1).asDate()
-#      """
-#    When iterated to list
-#    Then the result should be unordered
-#      | result |
-#      | dt[2023-09-06T16:28:29Z] |
-#
-#  @GraphComputerVerificationInjectionNotSupported
-#  Scenario: g_injectX1_2X_asDate
-#    Given the empty graph
-#    And using the parameter xx1 defined as "l[1,2]"
-#    And the traversal of
-#      """
-#      g.inject(xx1).asDate()
-#      """
-#    When iterated to list
-#    Then the traversal will raise an error with message containing text of 
"Can't parse"
-#
-#  @GraphComputerVerificationInjectionNotSupported
-#  Scenario: g_injectXnullX_asDate
-#    Given the empty graph
-#    And the traversal of
-#      """
-#      g.inject(null).asDate()
-#      """
-#    When iterated to list
-#    Then the traversal will raise an error with message containing text of 
"Can't parse"
-#
-#  @GraphComputerVerificationInjectionNotSupported
-#  Scenario: g_injectXinvalidstrX_asDate
-#    Given the empty graph
-#    And the traversal of
-#      """
-#      g.inject('This String is not an ISO 8601 Date').asDate()
-#      """
-#    When iterated to list
-#    Then the traversal will raise an error with message containing text of 
"Can't parse"
\ No newline at end of file
+
+  @GraphComputerVerificationInjectionNotSupported
+  Scenario: g_injectXstrX_asDate
+    Given the empty graph
+    And the traversal of
+      """
+      g.inject("2023-08-02T00:00:00Z").asDate()
+      """
+    When iterated to list
+    Then the result should be unordered
+      | result |
+      | dt[2023-08-02T00:00:00Z] |
+
+  @GraphComputerVerificationInjectionNotSupported
+  Scenario: g_injectX1694017707000X_asDate
+    Given the empty graph
+    And the traversal of
+      """
+      g.inject(1694017707000).asDate()
+      """
+    When iterated to list
+    Then the result should be unordered
+      | result |
+      | dt[2023-09-06T16:28:27Z] |
+
+  @GraphComputerVerificationInjectionNotSupported
+  Scenario: g_injectX1694017708000LX_asDate
+    Given the empty graph
+    And using the parameter xx1 defined as "d[1694017708000].l"
+    And the traversal of
+      """
+      g.inject(xx1).asDate()
+      """
+    When iterated to list
+    Then the result should be unordered
+      | result |
+      | dt[2023-09-06T16:28:28Z] |
+
+  @GraphComputerVerificationInjectionNotSupported
+  Scenario: g_injectX1694017709000dX_asDate
+    Given the empty graph
+    And using the parameter xx1 defined as "d[1694017709000.1].d"
+    And the traversal of
+      """
+      g.inject(xx1).asDate()
+      """
+    When iterated to list
+    Then the result should be unordered
+      | result |
+      | dt[2023-09-06T16:28:29Z] |
+
+  @GraphComputerVerificationInjectionNotSupported
+  Scenario: g_injectX1_2X_asDate
+    Given the empty graph
+    And using the parameter xx1 defined as "l[1,2]"
+    And the traversal of
+      """
+      g.inject(xx1).asDate()
+      """
+    When iterated to list
+    Then the traversal will raise an error with message containing text of 
"Can't parse"
+
+  @GraphComputerVerificationInjectionNotSupported
+  Scenario: g_injectXnullX_asDate
+    Given the empty graph
+    And the traversal of
+      """
+      g.inject(null).asDate()
+      """
+    When iterated to list
+    Then the traversal will raise an error with message containing text of 
"Can't parse"
+
+  @GraphComputerVerificationInjectionNotSupported
+  Scenario: g_injectXinvalidstrX_asDate
+    Given the empty graph
+    And the traversal of
+      """
+      g.inject('This String is not an ISO 8601 Date').asDate()
+      """
+    When iterated to list
+    Then the traversal will raise an error with message containing text of 
"Can't parse"
\ No newline at end of file
diff --git 
a/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/test/features/map/DateAdd.feature
 
b/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/test/features/map/DateAdd.feature
index c22dae07f2..939c7419bf 100644
--- 
a/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/test/features/map/DateAdd.feature
+++ 
b/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/test/features/map/DateAdd.feature
@@ -18,75 +18,75 @@
 # todo: re-enable after datetime is implemented
 @StepClassMap @StepDateAdd
 Feature: Step - dateAdd()
-#
-#  @GraphComputerVerificationInjectionNotSupported
-#  Scenario: g_injectXdatetimeXstrXX_dateAddXDT_hour_2X
-#    Given the empty graph
-#    And the traversal of
-#      """
-#      g.inject(datetime('2023-08-02T00:00:00Z')).dateAdd(DT.hour, 2)
-#      """
-#    When iterated to list
-#    Then the result should be unordered
-#      | result |
-#      | dt[2023-08-02T02:00:00Z] |
-#
-#  @GraphComputerVerificationInjectionNotSupported
-#  Scenario: g_injectXdatetimeXstrXX_dateAddXhour_2X
-#    Given the empty graph
-#    And the traversal of
-#      """
-#      g.inject(datetime('2023-08-02T00:00:00Z')).dateAdd(hour, 2)
-#      """
-#    When iterated to list
-#    Then the result should be unordered
-#      | result |
-#      | dt[2023-08-02T02:00:00Z] |
-#
-#  @GraphComputerVerificationInjectionNotSupported
-#  Scenario: g_injectXdatetimeXstrXX_dateAddXhour_1X
-#    Given the empty graph
-#    And the traversal of
-#      """
-#      g.inject(datetime('2023-08-02T00:00:00Z')).dateAdd(hour, -1)
-#      """
-#    When iterated to list
-#    Then the result should be unordered
-#      | result |
-#      | dt[2023-08-01T23:00:00Z] |
-#
-#  @GraphComputerVerificationInjectionNotSupported
-#  Scenario: g_injectXdatetimeXstrXX_dateAddXminute_10X
-#    Given the empty graph
-#    And the traversal of
-#      """
-#      g.inject(datetime('2023-08-02T00:00:00Z')).dateAdd(minute, 10)
-#      """
-#    When iterated to list
-#    Then the result should be unordered
-#      | result |
-#      | dt[2023-08-02T00:10:00Z] |
-#
-#  @GraphComputerVerificationInjectionNotSupported
-#  Scenario: g_injectXdatetimeXstrXX_dateAddXsecond_20X
-#    Given the empty graph
-#    And the traversal of
-#      """
-#      g.inject(datetime('2023-08-02T00:00:00Z')).dateAdd(second, 20)
-#      """
-#    When iterated to list
-#    Then the result should be unordered
-#      | result |
-#      | dt[2023-08-02T00:00:20Z] |
-#
-#  @GraphComputerVerificationInjectionNotSupported
-#  Scenario: g_injectXdatetimeXstrXX_dateAddXday_11X
-#    Given the empty graph
-#    And the traversal of
-#      """
-#      g.inject(datetime('2023-09-06T00:00:00Z')).dateAdd(day, 11)
-#      """
-#    When iterated to list
-#    Then the result should be unordered
-#      | result |
-#      | dt[2023-09-17T00:00:00Z] |
+
+  @GraphComputerVerificationInjectionNotSupported
+  Scenario: g_injectXdatetimeXstrXX_dateAddXDT_hour_2X
+    Given the empty graph
+    And the traversal of
+      """
+      g.inject(datetime('2023-08-02T00:00:00Z')).dateAdd(DT.hour, 2)
+      """
+    When iterated to list
+    Then the result should be unordered
+      | result |
+      | dt[2023-08-02T02:00:00Z] |
+
+  @GraphComputerVerificationInjectionNotSupported
+  Scenario: g_injectXdatetimeXstrXX_dateAddXhour_2X
+    Given the empty graph
+    And the traversal of
+      """
+      g.inject(datetime('2023-08-02T00:00:00Z')).dateAdd(hour, 2)
+      """
+    When iterated to list
+    Then the result should be unordered
+      | result |
+      | dt[2023-08-02T02:00:00Z] |
+
+  @GraphComputerVerificationInjectionNotSupported
+  Scenario: g_injectXdatetimeXstrXX_dateAddXhour_1X
+    Given the empty graph
+    And the traversal of
+      """
+      g.inject(datetime('2023-08-02T00:00:00Z')).dateAdd(hour, -1)
+      """
+    When iterated to list
+    Then the result should be unordered
+      | result |
+      | dt[2023-08-01T23:00:00Z] |
+
+  @GraphComputerVerificationInjectionNotSupported
+  Scenario: g_injectXdatetimeXstrXX_dateAddXminute_10X
+    Given the empty graph
+    And the traversal of
+      """
+      g.inject(datetime('2023-08-02T00:00:00Z')).dateAdd(minute, 10)
+      """
+    When iterated to list
+    Then the result should be unordered
+      | result |
+      | dt[2023-08-02T00:10:00Z] |
+
+  @GraphComputerVerificationInjectionNotSupported
+  Scenario: g_injectXdatetimeXstrXX_dateAddXsecond_20X
+    Given the empty graph
+    And the traversal of
+      """
+      g.inject(datetime('2023-08-02T00:00:00Z')).dateAdd(second, 20)
+      """
+    When iterated to list
+    Then the result should be unordered
+      | result |
+      | dt[2023-08-02T00:00:20Z] |
+
+  @GraphComputerVerificationInjectionNotSupported
+  Scenario: g_injectXdatetimeXstrXX_dateAddXday_11X
+    Given the empty graph
+    And the traversal of
+      """
+      g.inject(datetime('2023-09-06T00:00:00Z')).dateAdd(day, 11)
+      """
+    When iterated to list
+    Then the result should be unordered
+      | result |
+      | dt[2023-09-17T00:00:00Z] |
diff --git 
a/gremlin-util/src/test/java/org/apache/tinkerpop/gremlin/util/ser/binary/types/sample/SamplePerson.java
 
b/gremlin-util/src/test/java/org/apache/tinkerpop/gremlin/util/ser/binary/types/sample/SamplePerson.java
index 2970dce3bb..1e1f238038 100644
--- 
a/gremlin-util/src/test/java/org/apache/tinkerpop/gremlin/util/ser/binary/types/sample/SamplePerson.java
+++ 
b/gremlin-util/src/test/java/org/apache/tinkerpop/gremlin/util/ser/binary/types/sample/SamplePerson.java
@@ -18,7 +18,7 @@
  */
 package org.apache.tinkerpop.gremlin.util.ser.binary.types.sample;
 
-import java.util.Date;
+import java.time.OffsetDateTime;
 import java.util.Objects;
 
 /**
@@ -26,9 +26,9 @@ import java.util.Objects;
  */
 public class SamplePerson {
     private final String name;
-    private final Date birthDate;
+    private final OffsetDateTime birthDate;
 
-    SamplePerson(final String name, final Date birthDate) {
+    SamplePerson(final String name, final OffsetDateTime birthDate) {
         Objects.requireNonNull(name);
         Objects.requireNonNull(birthDate);
 
@@ -40,7 +40,7 @@ public class SamplePerson {
         return name;
     }
 
-    public Date getBirthDate() {
+    public OffsetDateTime getBirthDate() {
         return birthDate;
     }
 }
diff --git 
a/gremlin-util/src/test/java/org/apache/tinkerpop/gremlin/util/ser/binary/types/sample/SamplePersonSerializer.java
 
b/gremlin-util/src/test/java/org/apache/tinkerpop/gremlin/util/ser/binary/types/sample/SamplePersonSerializer.java
index 2a76206c72..a030ed46d7 100644
--- 
a/gremlin-util/src/test/java/org/apache/tinkerpop/gremlin/util/ser/binary/types/sample/SamplePersonSerializer.java
+++ 
b/gremlin-util/src/test/java/org/apache/tinkerpop/gremlin/util/ser/binary/types/sample/SamplePersonSerializer.java
@@ -27,7 +27,7 @@ import 
org.apache.tinkerpop.gremlin.structure.io.binary.types.CustomTypeSerializ
 
 import java.io.IOException;
 import java.nio.charset.StandardCharsets;
-import java.util.Date;
+import java.time.OffsetDateTime;
 
 /**
  * A sample custom type serializer.
@@ -78,7 +78,7 @@ public final class SamplePersonSerializer implements 
CustomTypeSerializer<Sample
         }
 
         final String name = context.readValue(buffer, String.class, false);
-        final Date birthDate = context.readValue(buffer, Date.class, false);
+        final OffsetDateTime birthDate = context.readValue(buffer, 
OffsetDateTime.class, false);
 
         return new SamplePerson(name, birthDate);
     }
diff --git 
a/gremlin-util/src/test/java/org/apache/tinkerpop/gremlin/util/ser/binary/types/sample/SamplePersonSerializerTest.java
 
b/gremlin-util/src/test/java/org/apache/tinkerpop/gremlin/util/ser/binary/types/sample/SamplePersonSerializerTest.java
index 1f4924efd1..d8b9d02060 100644
--- 
a/gremlin-util/src/test/java/org/apache/tinkerpop/gremlin/util/ser/binary/types/sample/SamplePersonSerializerTest.java
+++ 
b/gremlin-util/src/test/java/org/apache/tinkerpop/gremlin/util/ser/binary/types/sample/SamplePersonSerializerTest.java
@@ -35,9 +35,9 @@ import org.junit.Test;
 
 import java.io.IOException;
 import java.time.LocalDateTime;
+import java.time.OffsetDateTime;
 import java.time.ZoneOffset;
 import java.util.Collections;
-import java.util.Date;
 import java.util.HashMap;
 import java.util.Map;
 
@@ -46,8 +46,6 @@ import static 
org.apache.tinkerpop.gremlin.util.ser.AbstractMessageSerializer.TO
 import static 
org.apache.tinkerpop.gremlin.util.ser.GraphBinaryMessageSerializerV4.TOKEN_CUSTOM;
 import static org.hamcrest.MatcherAssert.assertThat;
 
-// todo: person contains removed date type, revisit after datetime is properly 
implemented
-@Ignore
 public class SamplePersonSerializerTest {
 
     private static final ByteBufAllocator allocator = ByteBufAllocator.DEFAULT;
@@ -89,7 +87,7 @@ public class SamplePersonSerializerTest {
         final GraphBinaryWriter writer = new GraphBinaryWriter(registry);
 
         final SamplePerson person = new SamplePerson("Matias",
-                Date.from(LocalDateTime.of(2005, 8, 5, 1, 
0).toInstant(ZoneOffset.UTC)));
+                OffsetDateTime.of(LocalDateTime.of(2005, 8, 5, 1, 0), 
ZoneOffset.UTC));
 
         for (boolean nullable: new boolean[] { true, false }) {
             final Buffer buffer = bufferFactory.create(allocator.buffer());
@@ -102,7 +100,7 @@ public class SamplePersonSerializerTest {
     }
 
     private void assertPerson(final GraphBinaryMessageSerializerV4 serializer) 
throws IOException {
-        final Date birthDate = Date.from(LocalDateTime.of(2010, 4, 29, 5, 
30).toInstant(ZoneOffset.UTC));
+        final OffsetDateTime birthDate = 
OffsetDateTime.of(LocalDateTime.of(2010, 4, 29, 5, 30), ZoneOffset.UTC);
         final SamplePerson person = new SamplePerson("Olivia", birthDate);
 
         final ByteBuf serialized = serializer.serializeResponseAsBinary(


Reply via email to