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

kenhuuu pushed a commit to branch stringify-params
in repository https://gitbox.apache.org/repos/asf/tinkerpop.git

commit b5423bb36ea630681209bb50b584e7d9b299cbd2
Author: Ken Hu <[email protected]>
AuthorDate: Thu Apr 23 19:51:17 2026 -0700

    change to seconds and nanos
---
 .../language/grammar/GenericLiteralVisitor.java    |  32 ++--
 .../translator/DotNetTranslateVisitor.java         |  19 ++-
 .../language/translator/GoTranslateVisitor.java    |  10 +-
 .../translator/GroovyTranslateVisitor.java         |  10 +-
 .../language/translator/JavaTranslateVisitor.java  |  10 +-
 .../translator/PythonTranslateVisitor.java         |  19 ++-
 .../gremlin/process/traversal/GremlinLang.java     |  13 +-
 .../grammar/GeneralLiteralVisitorTest.java         |  72 +++------
 .../language/translator/GremlinTranslatorTest.java |  38 +++--
 .../gremlin/process/traversal/GremlinLangTest.java |   5 -
 gremlin-dotnet/build/generate.groovy               |   1 -
 .../Gremlin.Net/Process/Traversal/GremlinLang.cs   |  12 +-
 .../Gherkin/CommonSteps.cs                         |  21 ++-
 .../Gremlin.Net.IntegrationTest/Gherkin/Gremlin.cs |  20 +--
 .../Process/Traversal/GremlinLangTests.cs          |  23 ---
 gremlin-go/driver/cucumber/cucumberSteps_test.go   |  49 +++---
 gremlin-go/driver/cucumber/gremlin.go              |  17 +--
 gremlin-go/driver/gremlinlang.go                   |  60 ++------
 gremlin-go/driver/gremlinlang_test.go              |  22 ---
 .../language/translator/DotNetTranslateVisitor.ts  |  77 ++--------
 .../lib/language/translator/GoTranslateVisitor.ts  |  42 +----
 .../language/translator/GroovyTranslateVisitor.ts  |  11 +-
 .../language/translator/JavaTranslateVisitor.ts    |  11 +-
 .../language/translator/PythonTranslateVisitor.ts  |  56 ++-----
 .../gremlin-javascript/test/cucumber/gremlin.js    |  17 +--
 gremlin-language/src/main/antlr4/Gremlin.g4        |   2 +-
 .../python/gremlin_python/process/traversal.py     |  48 ++----
 .../src/main/python/tests/feature/feature_steps.py |  21 ++-
 .../src/main/python/tests/feature/gremlin.py       |  17 +--
 .../python/tests/unit/process/test_gremlin_lang.py |   8 -
 .../tinkerpop/gremlin/features/StepDefinition.java |  17 ++-
 .../gremlin/language/translator/translations.json  | 170 ++++++++-------------
 .../gremlin/test/features/data/Duration.feature    |  82 +++-------
 33 files changed, 356 insertions(+), 676 deletions(-)

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 d6f76e2738..6a7f621c10 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
@@ -34,7 +34,6 @@ import java.math.BigInteger;
 import java.nio.ByteBuffer;
 import java.time.Duration;
 import java.time.OffsetDateTime;
-import java.time.format.DateTimeParseException;
 import java.util.ArrayList;
 import java.util.Base64;
 import java.util.HashSet;
@@ -542,23 +541,26 @@ public class GenericLiteralVisitor extends 
DefaultGremlinBaseVisitor<Object> {
      */
     @Override
     public Object visitDurationLiteral(final 
GremlinParser.DurationLiteralContext ctx) {
-        final String iso8601 = (String) 
antlr.genericVisitor.visitStringLiteral(ctx.stringLiteral());
-
-        // reject year/month components - check for Y or M before the T 
separator
-        final String upper = iso8601.toUpperCase();
-        final int tIndex = upper.indexOf('T');
-        final String datePart = tIndex >= 0 ? upper.substring(0, tIndex) : 
upper;
-        if (datePart.contains("Y") || datePart.contains("M")) {
-            throw new GremlinParserException(String.format(
-                    "Duration literal does not support year or month 
components: '%s'. Use days, hours, minutes, and seconds only.", iso8601));
-        }
+        final Number secondsNum = (Number) 
antlr.genericVisitor.visitIntegerLiteral(ctx.integerLiteral(0));
+        final Number nanosNum = (Number) 
antlr.genericVisitor.visitIntegerLiteral(ctx.integerLiteral(1));
 
-        try {
-            return Duration.parse(iso8601);
-        } catch (DateTimeParseException e) {
+        final long seconds = secondsNum.longValue();
+        final long nanos = nanosNum.longValue();
+
+        if (seconds < 0) {
             throw new GremlinParserException(
-                    String.format("Invalid Duration literal: '%s' is not a 
valid ISO-8601 duration", iso8601));
+                    String.format("Duration seconds must be non-negative, got: 
%d", seconds));
         }
+        if (nanos < 0 || nanos > 999999999) {
+            throw new GremlinParserException(
+                    String.format("Duration nanoseconds must be between 0 and 
999999999, got: %d", nanos));
+        }
+
+        final boolean isPositive = ctx.booleanLiteral() == null ||
+                Boolean.parseBoolean(ctx.booleanLiteral().getText());
+
+        final Duration d = Duration.ofSeconds(seconds, nanos);
+        return isPositive ? d : d.negated();
     }
 
     /**
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 663547b520..11546c6ca2 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
@@ -1195,16 +1195,15 @@ public class DotNetTranslateVisitor extends 
AbstractTranslateVisitor {
 
     @Override
     public Void visitDurationLiteral(final 
GremlinParser.DurationLiteralContext ctx) {
-        final String iso8601 = 
removeFirstAndLastCharacters(ctx.stringLiteral().getText());
-        // .NET's XmlConvert.ToTimeSpan requires "-PT30S" not "PT-30S", so 
parse and
-        // re-emit in the normalized form that .NET expects
-        final java.time.Duration d = java.time.Duration.parse(iso8601);
-        final String normalized = d.isNegative()
-                ? "-" + d.negated().toString()
-                : d.toString();
-        sb.append("XmlConvert.ToTimeSpan(\"");
-        sb.append(normalized);
-        sb.append("\")");
+        final long seconds = Long.parseLong(ctx.integerLiteral(0).getText());
+        final int nanos = Integer.parseInt(ctx.integerLiteral(1).getText());
+        final boolean isPositive = ctx.booleanLiteral() == null ||
+                Boolean.parseBoolean(ctx.booleanLiteral().getText());
+        // Convert to ticks: 1 tick = 100 nanoseconds, 1 second = 10,000,000 
ticks
+        final long ticks = seconds * 10_000_000L + nanos / 100;
+        sb.append(String.format("TimeSpan.FromTicks(%dL)", ticks));
+        if (!isPositive)
+            sb.append(".Negate()");
         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 7a81b84a72..f9c30a017f 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
@@ -28,7 +28,6 @@ import 
org.apache.tinkerpop.gremlin.process.traversal.strategy.decoration.Option
 import org.apache.tinkerpop.gremlin.structure.VertexProperty;
 import org.apache.tinkerpop.gremlin.util.DatetimeHelper;
 
-import java.time.Duration;
 import java.time.OffsetDateTime;
 import java.util.Arrays;
 import java.util.Base64;
@@ -355,9 +354,12 @@ public class GoTranslateVisitor extends 
AbstractTranslateVisitor {
 
     @Override
     public Void visitDurationLiteral(final 
GremlinParser.DurationLiteralContext ctx) {
-        final String iso8601 = 
removeFirstAndLastCharacters(ctx.stringLiteral().getText());
-        final Duration d = Duration.parse(iso8601);
-        sb.append("time.Duration(").append(d.toNanos()).append(")");
+        final long seconds = Long.parseLong(ctx.integerLiteral(0).getText());
+        final int nanos = Integer.parseInt(ctx.integerLiteral(1).getText());
+        final boolean isPositive = ctx.booleanLiteral() == null ||
+                Boolean.parseBoolean(ctx.booleanLiteral().getText());
+        final long totalNanos = seconds * 1_000_000_000L + nanos;
+        sb.append("time.Duration(").append(isPositive ? totalNanos : 
-totalNanos).append(")");
         return null;
     }
 
diff --git 
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/language/translator/GroovyTranslateVisitor.java
 
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/language/translator/GroovyTranslateVisitor.java
index a6e1f6050a..009233c9eb 100644
--- 
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/language/translator/GroovyTranslateVisitor.java
+++ 
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/language/translator/GroovyTranslateVisitor.java
@@ -142,9 +142,13 @@ public class GroovyTranslateVisitor extends 
TranslateVisitor {
 
     @Override
     public Void visitDurationLiteral(final 
GremlinParser.DurationLiteralContext ctx) {
-        sb.append("Duration.parse(");
-        sb.append(ctx.stringLiteral().getText());
-        sb.append(")");
+        final long seconds = Long.parseLong(ctx.integerLiteral(0).getText());
+        final int nanos = Integer.parseInt(ctx.integerLiteral(1).getText());
+        final boolean isPositive = ctx.booleanLiteral() == null ||
+                Boolean.parseBoolean(ctx.booleanLiteral().getText());
+        sb.append(String.format("Duration.ofSeconds(%d, %d)", seconds, nanos));
+        if (!isPositive)
+            sb.append(".negated()");
         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 9a0c7dbdb5..ee03430118 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
@@ -260,9 +260,13 @@ public class JavaTranslateVisitor extends 
AbstractTranslateVisitor {
 
     @Override
     public Void visitDurationLiteral(final 
GremlinParser.DurationLiteralContext ctx) {
-        sb.append("Duration.parse(");
-        sb.append(ctx.stringLiteral().getText());
-        sb.append(")");
+        final long seconds = Long.parseLong(ctx.integerLiteral(0).getText());
+        final int nanos = Integer.parseInt(ctx.integerLiteral(1).getText());
+        final boolean isPositive = ctx.booleanLiteral() == null ||
+                Boolean.parseBoolean(ctx.booleanLiteral().getText());
+        sb.append(String.format("Duration.ofSeconds(%d, %d)", seconds, nanos));
+        if (!isPositive)
+            sb.append(".negated()");
         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 9a9699de88..e6297dc539 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
@@ -26,7 +26,6 @@ import org.apache.tinkerpop.gremlin.structure.VertexProperty;
 import org.apache.tinkerpop.gremlin.util.DatetimeHelper;
 
 import java.math.BigInteger;
-import java.time.Duration;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -301,15 +300,19 @@ public class PythonTranslateVisitor extends 
AbstractTranslateVisitor {
 
     @Override
     public Void visitDurationLiteral(final 
GremlinParser.DurationLiteralContext ctx) {
-        final String iso8601 = 
removeFirstAndLastCharacters(ctx.stringLiteral().getText());
-        final Duration d = Duration.parse(iso8601);
-        final long totalSeconds = d.getSeconds();
-        final int nanos = d.getNano();
-        if (nanos == 0) {
+        final long seconds = Long.parseLong(ctx.integerLiteral(0).getText());
+        final int nanos = Integer.parseInt(ctx.integerLiteral(1).getText());
+        final boolean isPositive = ctx.booleanLiteral() == null ||
+                Boolean.parseBoolean(ctx.booleanLiteral().getText());
+        final long totalSeconds = isPositive ? seconds : -seconds;
+        // Python's timedelta has microsecond resolution; sub-microsecond 
nanos are truncated
+        final long micros = nanos / 1000;
+        if (micros == 0) {
             sb.append("timedelta(seconds=").append(totalSeconds).append(")");
         } else {
-            final long micros = nanos / 1000;
-            
sb.append("timedelta(seconds=").append(totalSeconds).append(",microseconds=").append(micros).append(")");
+            // for negative durations, microseconds must also be negated
+            final long totalMicros = isPositive ? micros : -micros;
+            
sb.append("timedelta(seconds=").append(totalSeconds).append(",microseconds=").append(totalMicros).append(")");
         }
         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 d895f6ec5b..aa00fccb8c 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
@@ -155,8 +155,17 @@ public class GremlinLang implements Cloneable, 
Serializable {
             // is pure ASCII and avoids encoding issues across different 
platforms
             return String.format("\"%s\"c", 
StringEscapeUtils.escapeJava(arg.toString()));
 
-        if (arg instanceof Duration)
-            return String.format("Duration(\"%s\")", arg);
+        if (arg instanceof Duration) {
+            final Duration d = (Duration) arg;
+            final boolean isNegative = d.isNegative();
+            // negate to get magnitude components - Java's Duration stores 
negative values
+            // with adjusted seconds (e.g. -1.5s is seconds=-2, 
nanos=500000000)
+            final Duration abs = isNegative ? d.negated() : d;
+            if (isNegative)
+                return String.format("Duration(%d,%d,false)", 
abs.getSeconds(), abs.getNano());
+            else
+                return String.format("Duration(%d,%d)", abs.getSeconds(), 
abs.getNano());
+        }
 
         if (arg instanceof ByteBuffer) {
             // duplicate() shares the underlying data but gives an independent 
position cursor,
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 7dd40a61fb..ed519b6b31 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
@@ -941,22 +941,17 @@ public class GeneralLiteralVisitorTest {
         @Parameterized.Parameters(name = "{0}")
         public static Iterable<Object[]> generateTestParameters() {
             return Arrays.asList(new Object[][]{
-                    {"Duration(\"PT2H30M\")", 
Duration.ofHours(2).plusMinutes(30)},
-                    {"Duration(\"PT0S\")", Duration.ZERO},
-                    {"Duration(\"P1DT12H\")", 
Duration.ofDays(1).plusHours(12)},
-                    {"Duration(\"PT-30S\")", Duration.ofSeconds(-30)},
-                    {"Duration(\"PT0.5S\")", Duration.ofMillis(500)},
-                    {"Duration(\"-PT30S\")", Duration.ofSeconds(-30)},
-                    {"Duration(\"-P1DT12H\")", Duration.ofHours(-36)},
-                    {"Duration(\"P2D\")", Duration.ofDays(2)},
-                    {"Duration(\"PT1H30M15S\")", 
Duration.ofHours(1).plusMinutes(30).plusSeconds(15)},
-                    {"Duration(\"P0D\")", Duration.ZERO},
-                    {"Duration(\"PT0.000000001S\")", Duration.ofNanos(1)},
-                    {"Duration(\"PT36H\")", Duration.ofHours(36)},
-                    {"Duration(\"PT0.0000001S\")", Duration.ofNanos(100)},
-                    {"Duration(\"PT0.000001S\")", Duration.ofNanos(1000)},
-                    {"Duration(\"PT-0.5S\")", Duration.ofMillis(-500)},
-                    {"Duration(\"-PT0.5S\")", Duration.ofMillis(-500)},
+                    {"Duration(9000, 0)", Duration.ofHours(2).plusMinutes(30)},
+                    {"Duration(0, 0)", Duration.ZERO},
+                    {"Duration(30, 0)", Duration.ofSeconds(30)},
+                    {"Duration(0, 500000000)", Duration.ofMillis(500)},
+                    {"Duration(5415, 0)", 
Duration.ofHours(1).plusMinutes(30).plusSeconds(15)},
+                    {"Duration(0, 1)", Duration.ofNanos(1)},
+                    {"Duration(1, 500000000)", 
Duration.ofSeconds(1).plusMillis(500)},
+                    {"Duration(30, 0, false)", Duration.ofSeconds(-30)},
+                    {"Duration(0, 500000000, false)", Duration.ofMillis(-500)},
+                    {"Duration(0, 0, false)", Duration.ZERO},
+                    {"Duration(0, 0, true)", Duration.ZERO},
             });
         }
 
@@ -971,62 +966,41 @@ public class GeneralLiteralVisitorTest {
 
     public static class InvalidDurationLiteralTest {
         @Test
-        public void shouldFailOnInvalidDuration() {
-            final GremlinLexer lexer = new 
GremlinLexer(CharStreams.fromString("Duration(\"not-a-duration\")"));
+        public void shouldFailOnNegativeNanos() {
+            final GremlinLexer lexer = new 
GremlinLexer(CharStreams.fromString("Duration(0, -1)"));
             final GremlinParser parser = new GremlinParser(new 
CommonTokenStream(lexer));
             final GremlinParser.DurationLiteralContext ctx = 
parser.durationLiteral();
             try {
                 new GenericLiteralVisitor(new 
GremlinAntlrToJava()).visitDurationLiteral(ctx);
-                fail("Invalid Duration value should have thrown exception");
+                fail("Negative nanos should have thrown exception");
             } catch (GremlinParserException gpe) {
-                assertThat(gpe.getMessage().contains("Invalid Duration 
literal:"), Matchers.is(true));
-            }
-        }
-
-        @Test(expected = GremlinParserException.class)
-        public void shouldFailOnEmptyDuration() {
-            final GremlinLexer lexer = new 
GremlinLexer(CharStreams.fromString("Duration(\"\")"));
-            final GremlinParser parser = new GremlinParser(new 
CommonTokenStream(lexer));
-            final GremlinParser.DurationLiteralContext ctx = 
parser.durationLiteral();
-            new GenericLiteralVisitor(new 
GremlinAntlrToJava()).visitDurationLiteral(ctx);
-        }
-
-        @Test
-        public void shouldFailOnYearComponent() {
-            final GremlinLexer lexer = new 
GremlinLexer(CharStreams.fromString("Duration(\"P1Y\")"));
-            final GremlinParser parser = new GremlinParser(new 
CommonTokenStream(lexer));
-            final GremlinParser.DurationLiteralContext ctx = 
parser.durationLiteral();
-            try {
-                new GenericLiteralVisitor(new 
GremlinAntlrToJava()).visitDurationLiteral(ctx);
-                fail("Year component should have thrown exception");
-            } catch (GremlinParserException gpe) {
-                assertThat(gpe.getMessage().contains("does not support year or 
month components"), Matchers.is(true));
+                assertThat(gpe.getMessage().contains("nanoseconds must be 
between 0 and 999999999"), Matchers.is(true));
             }
         }
 
         @Test
-        public void shouldFailOnMonthComponent() {
-            final GremlinLexer lexer = new 
GremlinLexer(CharStreams.fromString("Duration(\"P6M\")"));
+        public void shouldFailOnNanosOverflow() {
+            final GremlinLexer lexer = new 
GremlinLexer(CharStreams.fromString("Duration(0, 1000000000)"));
             final GremlinParser parser = new GremlinParser(new 
CommonTokenStream(lexer));
             final GremlinParser.DurationLiteralContext ctx = 
parser.durationLiteral();
             try {
                 new GenericLiteralVisitor(new 
GremlinAntlrToJava()).visitDurationLiteral(ctx);
-                fail("Month component should have thrown exception");
+                fail("Nanos overflow should have thrown exception");
             } catch (GremlinParserException gpe) {
-                assertThat(gpe.getMessage().contains("does not support year or 
month components"), Matchers.is(true));
+                assertThat(gpe.getMessage().contains("nanoseconds must be 
between 0 and 999999999"), Matchers.is(true));
             }
         }
 
         @Test
-        public void shouldFailOnYearMonthDayComponent() {
-            final GremlinLexer lexer = new 
GremlinLexer(CharStreams.fromString("Duration(\"P1Y6M3DT4H\")"));
+        public void shouldFailOnNegativeSeconds() {
+            final GremlinLexer lexer = new 
GremlinLexer(CharStreams.fromString("Duration(-1, 0)"));
             final GremlinParser parser = new GremlinParser(new 
CommonTokenStream(lexer));
             final GremlinParser.DurationLiteralContext ctx = 
parser.durationLiteral();
             try {
                 new GenericLiteralVisitor(new 
GremlinAntlrToJava()).visitDurationLiteral(ctx);
-                fail("Year/month component should have thrown exception");
+                fail("Negative seconds should have thrown exception");
             } catch (GremlinParserException gpe) {
-                assertThat(gpe.getMessage().contains("does not support year or 
month components"), Matchers.is(true));
+                assertThat(gpe.getMessage().contains("seconds must be 
non-negative"), Matchers.is(true));
             }
         }
     }
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 a8792c2b5a..050787e8f8 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
@@ -1435,24 +1435,42 @@ public class GremlinTranslatorTest {
                             "g.inject('a')",
                             "Character literals are not supported in 
JavaScript",
                             "g.inject(SingleChar('a'))"},
-                    {"g.inject(Duration(\"PT2H30M\"))",
+                    {"g.inject(Duration(9000,0))",
                             null,
                             "g.inject(duration0)",
-                            
"g.Inject<object>(XmlConvert.ToTimeSpan(\"PT2H30M\"))",
+                            
"g.Inject<object>(TimeSpan.FromTicks(90000000000L))",
                             "g.Inject(time.Duration(9000000000000))",
-                            "g.inject(Duration.parse(\"PT2H30M\"))",
-                            "g.inject(Duration.parse(\"PT2H30M\"))",
+                            "g.inject(Duration.ofSeconds(9000, 0))",
+                            "g.inject(Duration.ofSeconds(9000, 0))",
                             "Duration literals are not supported in 
JavaScript",
                             "g.inject(timedelta(seconds=9000))"},
-                    {"g.inject(Duration(\"PT2H-30M\"))",
+                    {"g.inject(Duration(30,0,false))",
                             null,
                             "g.inject(duration0)",
-                            
"g.Inject<object>(XmlConvert.ToTimeSpan(\"PT1H30M\"))",
-                            "g.Inject(time.Duration(5400000000000))",
-                            "g.inject(Duration.parse(\"PT2H-30M\"))",
-                            "g.inject(Duration.parse(\"PT2H-30M\"))",
+                            
"g.Inject<object>(TimeSpan.FromTicks(300000000L).Negate())",
+                            "g.Inject(time.Duration(-30000000000))",
+                            "g.inject(Duration.ofSeconds(30, 0).negated())",
+                            "g.inject(Duration.ofSeconds(30, 0).negated())",
                             "Duration literals are not supported in 
JavaScript",
-                            "g.inject(timedelta(seconds=5400))"},
+                            "g.inject(timedelta(seconds=-30))"},
+                    {"g.inject(Duration(1,500000000))",
+                            null,
+                            "g.inject(duration0)",
+                            "g.Inject<object>(TimeSpan.FromTicks(15000000L))",
+                            "g.Inject(time.Duration(1500000000))",
+                            "g.inject(Duration.ofSeconds(1, 500000000))",
+                            "g.inject(Duration.ofSeconds(1, 500000000))",
+                            "Duration literals are not supported in 
JavaScript",
+                            
"g.inject(timedelta(seconds=1,microseconds=500000))"},
+                    {"g.inject(Duration(0,500000000,false))",
+                            null,
+                            "g.inject(duration0)",
+                            
"g.Inject<object>(TimeSpan.FromTicks(5000000L).Negate())",
+                            "g.Inject(time.Duration(-500000000))",
+                            "g.inject(Duration.ofSeconds(0, 
500000000).negated())",
+                            "g.inject(Duration.ofSeconds(0, 
500000000).negated())",
+                            "Duration literals are not supported in 
JavaScript",
+                            
"g.inject(timedelta(seconds=0,microseconds=-500000))"},
                     {"g.inject(Binary(\"AQID\"))",
                             null,
                             "g.inject(bytebuffer0)",
diff --git 
a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/GremlinLangTest.java
 
b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/GremlinLangTest.java
index a86fb444e5..b7f9da3290 100644
--- 
a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/GremlinLangTest.java
+++ 
b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/GremlinLangTest.java
@@ -38,7 +38,6 @@ import org.junit.runners.Parameterized;
 import java.math.BigDecimal;
 import java.math.BigInteger;
 import java.nio.ByteBuffer;
-import java.time.Duration;
 import java.util.Arrays;
 import java.util.Collections;
 import java.util.Date;
@@ -134,10 +133,6 @@ public class GremlinLangTest {
                 {g.inject('\''), "g.inject(\"'\"c)"},
                                // Character - backslash (not in feature file 
due to Gherkin escaping issues)
                 {g.inject('\\'), "g.inject(\"\\\\\"c)"},
-                // Duration - Java-specific: normalization of days to hours, 
nanosecond precision
-                {g.inject(Duration.ofDays(1).plusHours(12)), 
"g.inject(Duration(\"PT36H\"))"},
-                {g.inject(Duration.ofNanos(1)), 
"g.inject(Duration(\"PT0.000000001S\"))"},
-                {g.inject(Duration.ofMillis(-500)), 
"g.inject(Duration(\"PT-0.5S\"))"},
                 // Binary - byte[] type (distinct from ByteBuffer)
                 {g.inject(new byte[]{1, 2, 3}), "g.inject(Binary(\"AQID\"))"},
                 {g.inject(new byte[]{}), "g.inject(Binary(\"\"))"},
diff --git a/gremlin-dotnet/build/generate.groovy 
b/gremlin-dotnet/build/generate.groovy
index 234dfb6950..24bc271ad5 100644
--- a/gremlin-dotnet/build/generate.groovy
+++ b/gremlin-dotnet/build/generate.groovy
@@ -61,7 +61,6 @@ radishGremlinFile.withWriter('UTF-8') { Writer writer ->
     writer.writeLine('using System;\n' +
                      'using System.Numerics;\n' +
                      'using System.Collections.Generic;\n' +
-                     'using System.Xml;\n' +
                      'using Gremlin.Net.Structure;\n' +
                      'using Gremlin.Net.Process.Traversal;\n' +
                      'using 
Gremlin.Net.Process.Traversal.Strategy.Optimization;\n' +
diff --git a/gremlin-dotnet/src/Gremlin.Net/Process/Traversal/GremlinLang.cs 
b/gremlin-dotnet/src/Gremlin.Net/Process/Traversal/GremlinLang.cs
index 4de5cdcc12..2dfdc02fd5 100644
--- a/gremlin-dotnet/src/Gremlin.Net/Process/Traversal/GremlinLang.cs
+++ b/gremlin-dotnet/src/Gremlin.Net/Process/Traversal/GremlinLang.cs
@@ -28,7 +28,6 @@ using System.Globalization;
 using System.Numerics;
 using System.Text;
 using System.Threading;
-using System.Xml;
 using Gremlin.Net.Process.Traversal.Strategy;
 using Gremlin.Net.Process.Traversal.Strategy.Decoration;
 using Gremlin.Net.Structure;
@@ -243,8 +242,15 @@ namespace Gremlin.Net.Process.Traversal
                 return $"\"{EscapeJava(charVal.ToString())}\"c";
 
             if (arg is TimeSpan timeSpan)
-                return $"Duration(\"{XmlConvert.ToString(timeSpan)}\")";
-
+            {
+                // Use integer tick arithmetic to avoid float precision loss
+                var absTicks = Math.Abs(timeSpan.Ticks);
+                var totalSeconds = absTicks / TimeSpan.TicksPerSecond;
+                var nanos = (int)((absTicks % TimeSpan.TicksPerSecond) * 100);
+                return timeSpan < TimeSpan.Zero
+                    ? $"Duration({totalSeconds},{nanos},false)"
+                    : $"Duration({totalSeconds},{nanos})";
+            }
             if (arg is byte[] byteArray)
                 return $"Binary(\"{Convert.ToBase64String(byteArray)}\")";
 
diff --git 
a/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/CommonSteps.cs 
b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/CommonSteps.cs
index 65e7f9fa51..4921813393 100644
--- a/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/CommonSteps.cs
+++ b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/CommonSteps.cs
@@ -549,18 +549,15 @@ namespace Gremlin.Net.IntegrationTest.Gherkin
             return value[0];
         }
 
-        private static object ToDuration(string iso8601, string graphName)
-        {
-            // Java's Duration.toString() produces negative components like 
"PT-30S"
-            // but XmlConvert.ToTimeSpan only supports the leading prefix form 
"-PT30S".
-            // Normalize by moving the negative sign to the front.
-            var normalized = iso8601;
-            if (!iso8601.StartsWith("-") && iso8601.Contains("-"))
-            {
-                // Remove negatives from components and add leading minus
-                normalized = "-" + iso8601.Replace("-", "");
-            }
-            return System.Xml.XmlConvert.ToTimeSpan(normalized);
+        private static object ToDuration(string value, string graphName)
+        {
+            var parts = value.Split(',');
+            var seconds = long.Parse(parts[0].Trim());
+            var nanos = int.Parse(parts[1].Trim());
+            var isPositive = parts.Length < 3 || bool.Parse(parts[2].Trim());
+            // TimeSpan has 100-nanosecond tick resolution; sub-100ns values 
are truncated
+            var ts = TimeSpan.FromSeconds(seconds) + TimeSpan.FromTicks(nanos 
/ 100);
+            return isPositive ? ts : ts.Negate();
         }
 
         private static object ToBinary(string base64, string graphName)
diff --git a/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/Gremlin.cs 
b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/Gremlin.cs
index 392d7aa296..bf88cfccfa 100644
--- a/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/Gremlin.cs
+++ b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/Gremlin.cs
@@ -32,7 +32,6 @@
 using System;
 using System.Numerics;
 using System.Collections.Generic;
-using System.Xml;
 using Gremlin.Net.Structure;
 using Gremlin.Net.Process.Traversal;
 using Gremlin.Net.Process.Traversal.Strategy.Optimization;
@@ -264,17 +263,14 @@ namespace Gremlin.Net.IntegrationTest.Gherkin
                {"g_V_valuesXdoubleX_isXtypeOfXGType_DOUBLEXX_order_byXascX", 
new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> 
{(g,p) =>g.AddV((string) "data").Property("double", 3.2d).AddV((string) 
"data").Property("double", 1.8d).AddV((string) "data").Property("double", 
2.5d), (g,p) 
=>g.V().Values<object>("double").Is(P.TypeOf(GType.Double)).Order().By(Order.Asc)}},
 
                {"g_injectX5_5dX_isXtypeOfXGType_DOUBLEXX_groupCount", new 
List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> 
{(g,p) 
=>g.Inject<object>(5.5d).Is(P.TypeOf(GType.Double)).GroupCount<object>()}}, 
                {"g_V_valuesXageX_isXtypeOfXGType_DOUBLEXX", new 
List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> 
{(g,p) =>g.V().Values<object>("age").Is(P.TypeOf(GType.Double))}}, 
-               {"g_injectXDurationXPT2H30MXX", new 
List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> 
{(g,p) =>g.Inject<object>(XmlConvert.ToTimeSpan("PT2H30M"))}}, 
-               {"g_injectXDurationXPT0SXX", new 
List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> 
{(g,p) =>g.Inject<object>(XmlConvert.ToTimeSpan("PT0S"))}}, 
-               {"g_injectXDurationXPTneg30SXX", new 
List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> 
{(g,p) =>g.Inject<object>(XmlConvert.ToTimeSpan("-PT30S"))}}, 
-               {"g_injectXDurationXnegPT30SXX", new 
List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> 
{(g,p) =>g.Inject<object>(XmlConvert.ToTimeSpan("-PT30S"))}}, 
-               {"g_injectXDurationXPT0_5SXX", new 
List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> 
{(g,p) =>g.Inject<object>(XmlConvert.ToTimeSpan("PT0.5S"))}}, 
-               {"g_injectXDurationXP1DT12HXX", new 
List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> 
{(g,p) =>g.Inject<object>(XmlConvert.ToTimeSpan("PT36H"))}}, 
-               {"g_injectXDurationXP2DXX", new List<Func<GraphTraversalSource, 
IDictionary<string, object>, ITraversal>> {(g,p) 
=>g.Inject<object>(XmlConvert.ToTimeSpan("PT48H"))}}, 
-               {"g_injectXDurationXPT1H30M15SXX", new 
List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> 
{(g,p) =>g.Inject<object>(XmlConvert.ToTimeSpan("PT1H30M15S"))}}, 
-               {"g_injectXDurationXPTneg0_5SXX", new 
List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> 
{(g,p) =>g.Inject<object>(XmlConvert.ToTimeSpan("-PT0.5S"))}}, 
-               {"g_valuesXlengthX_isXtypeOfXGType_DURATIONXX", new 
List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> 
{(g,p) =>g.AddV((string) "data").Property("length", 
XmlConvert.ToTimeSpan("PT2H30M")), (g,p) 
=>g.V().Values<object>("length").Is(P.TypeOf(GType.Duration))}}, 
-               {"g_injectXDurationXPT2H30MXX_isXgtXDurationXPT1HXXX", new 
List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> 
{(g,p) 
=>g.Inject<object>(XmlConvert.ToTimeSpan("PT2H30M")).Is(P.Gt(XmlConvert.ToTimeSpan("PT1H")))}},
 
+               {"g_injectXDurationX9000_0XX", new 
List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> 
{(g,p) =>g.Inject<object>(TimeSpan.FromTicks(90000000000L))}}, 
+               {"g_injectXDurationX0_0XX", new List<Func<GraphTraversalSource, 
IDictionary<string, object>, ITraversal>> {(g,p) 
=>g.Inject<object>(TimeSpan.FromTicks(0L))}}, 
+               {"g_injectXDurationX0_500000000XX", new 
List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> 
{(g,p) =>g.Inject<object>(TimeSpan.FromTicks(5000000L))}}, 
+               {"g_injectXDurationX30_0XX", new 
List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> 
{(g,p) =>g.Inject<object>(TimeSpan.FromTicks(300000000L))}}, 
+               {"g_injectXDurationX30_0_falseXX", new 
List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> 
{(g,p) =>g.Inject<object>(TimeSpan.FromTicks(300000000L).Negate())}}, 
+               {"g_injectXDurationX1_500000000_falseXX", new 
List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> 
{(g,p) =>g.Inject<object>(TimeSpan.FromTicks(15000000L).Negate())}}, 
+               {"g_valuesXlengthX_isXtypeOfXGType_DURATIONXX", new 
List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> 
{(g,p) =>g.AddV((string) "data").Property("length", 
TimeSpan.FromTicks(90000000000L)), (g,p) 
=>g.V().Values<object>("length").Is(P.TypeOf(GType.Duration))}}, 
+               {"g_injectXDurationX9000_0XX_isXgtXDurationX3600_0XXX", new 
List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> 
{(g,p) 
=>g.Inject<object>(TimeSpan.FromTicks(90000000000L)).Is(P.Gt(TimeSpan.FromTicks(36000000000L)))}},
 
                {"g_V_valuesXfloatX_isXtypeOfXGType_FLOATXX", new 
List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> 
{(g,p) =>g.AddV((string) "data").Property("float", 2.5), (g,p) 
=>g.V().Values<object>("float").AsNumber(GType.Float).Is(P.TypeOf(GType.Float))}},
 
                {"g_V_valuesXfloatX_isXtypeOfXGType_FLOATXX_mathXmulX2XX", new 
List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> 
{(g,p) =>g.AddV((string) "data").Property("float", 3.0), (g,p) 
=>g.V().Values<object>("float").AsNumber(GType.Float).Is(P.TypeOf(GType.Float)).Math("_
 * 2")}}, 
                {"g_V_valuesXfloatX_isXtypeOfXGType_FLOATXX_isXeqX1_5XX", new 
List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> 
{(g,p) =>g.AddV((string) "data").Property("float", 1.5), (g,p) 
=>g.V().Values<object>("float").AsNumber(GType.Float).Is(P.TypeOf(GType.Float)).Is(P.Eq(1.5))}},
 
diff --git 
a/gremlin-dotnet/test/Gremlin.Net.UnitTest/Process/Traversal/GremlinLangTests.cs
 
b/gremlin-dotnet/test/Gremlin.Net.UnitTest/Process/Traversal/GremlinLangTests.cs
index e25833ff21..f54f4e359b 100644
--- 
a/gremlin-dotnet/test/Gremlin.Net.UnitTest/Process/Traversal/GremlinLangTests.cs
+++ 
b/gremlin-dotnet/test/Gremlin.Net.UnitTest/Process/Traversal/GremlinLangTests.cs
@@ -1057,28 +1057,5 @@ namespace Gremlin.Net.UnitTest.Process.Traversal
             Assert.Equal("g.inject(\"'\"c)",
                 _g.Inject((object)'\'').GremlinLang.GetGremlin());
         }
-
-        // Duration - C#-specific: XmlConvert format with days, tick 
precision, negative prefix
-        [Fact]
-        public void g_Inject_Duration_DaysAndHours()
-        {
-            Assert.Equal("g.inject(Duration(\"P1DT12H\"))",
-                _g.Inject((object)(TimeSpan.FromDays(1) + 
TimeSpan.FromHours(12))).GremlinLang.GetGremlin());
-        }
-
-        [Fact]
-        public void g_Inject_Duration_TickPrecision()
-        {
-            // TimeSpan tick = 100 nanoseconds
-            Assert.Equal("g.inject(Duration(\"PT0.0000001S\"))",
-                
_g.Inject((object)TimeSpan.FromTicks(1)).GremlinLang.GetGremlin());
-        }
-
-        [Fact]
-        public void g_Inject_Duration_NegativeSubSecond()
-        {
-            Assert.Equal("g.inject(Duration(\"-PT0.5S\"))",
-                
_g.Inject((object)TimeSpan.FromMilliseconds(-500)).GremlinLang.GetGremlin());
-        }
     }
 }
diff --git a/gremlin-go/driver/cucumber/cucumberSteps_test.go 
b/gremlin-go/driver/cucumber/cucumberSteps_test.go
index ef4921936a..2d72befcb7 100644
--- a/gremlin-go/driver/cucumber/cucumberSteps_test.go
+++ b/gremlin-go/driver/cucumber/cucumberSteps_test.go
@@ -47,8 +47,6 @@ type tinkerPopGraph struct {
 
 var parsers map[*regexp.Regexp]func(string, string) interface{}
 
-var iso8601DurationRe = 
regexp.MustCompile(`^(-?)PT(?:(-?\d+)H)?(?:(-?\d+)M)?(?:(-?\d+(?:\.\d+)?)S)?$`)
-
 func init() {
        parsers = map[*regexp.Regexp]func(string, string) interface{}{
                regexp.MustCompile(`^str\[(.*)]$`):        func(stringVal, 
graphName string) interface{} { return stringVal }, //returns the string value 
as is
@@ -136,12 +134,28 @@ func toUuid(stringVal, graphName string) interface{} {
        return val
 }
 
-// Parse duration from ISO-8601 string (e.g., "PT2H30M", "PT-30S").
+// Parse duration from seconds,nanos[,isPositive] format.
 func toDuration(stringVal, graphName string) interface{} {
-       d, err := parseISO8601Duration(stringVal)
+       parts := strings.Split(stringVal, ",")
+       if len(parts) < 2 {
+               return nil
+       }
+       seconds, err := strconv.ParseInt(strings.TrimSpace(parts[0]), 10, 64)
+       if err != nil {
+               return nil
+       }
+       nanos, err := strconv.ParseInt(strings.TrimSpace(parts[1]), 10, 64)
        if err != nil {
                return nil
        }
+       isPositive := true
+       if len(parts) >= 3 {
+               isPositive = strings.TrimSpace(parts[2]) == "true"
+       }
+       d := time.Duration(seconds)*time.Second + time.Duration(nanos)
+       if !isPositive {
+               d = -d
+       }
        return d
 }
 
@@ -154,33 +168,6 @@ func toBinary(stringVal, graphName string) interface{} {
        return &gremlingo.ByteBuffer{Data: data}
 }
 
-// parseISO8601Duration parses an ISO-8601 duration string (as produced by 
Java's Duration.toString())
-// into a time.Duration. Supports formats like "PT2H30M", "PT-30S", "PT0.5S".
-func parseISO8601Duration(s string) (time.Duration, error) {
-       m := iso8601DurationRe.FindStringSubmatch(s)
-       if m == nil {
-               return 0, fmt.Errorf("invalid ISO-8601 duration: %s", s)
-       }
-       sign := time.Duration(1)
-       if m[1] == "-" {
-               sign = -1
-       }
-       var d time.Duration
-       if m[2] != "" {
-               h, _ := strconv.ParseInt(m[2], 10, 64)
-               d += time.Duration(h) * time.Hour
-       }
-       if m[3] != "" {
-               min, _ := strconv.ParseInt(m[3], 10, 64)
-               d += time.Duration(min) * time.Minute
-       }
-       if m[4] != "" {
-               sec, _ := strconv.ParseFloat(m[4], 64)
-               d += time.Duration(sec * float64(time.Second))
-       }
-       return sign * d, nil
-}
-
 // Parse numeric.
 func toNumeric(stringVal, graphName string) interface{} {
        if strings.Contains(stringVal, ".") {
diff --git a/gremlin-go/driver/cucumber/gremlin.go 
b/gremlin-go/driver/cucumber/gremlin.go
index b20c1ac9fd..2c821d785d 100644
--- a/gremlin-go/driver/cucumber/gremlin.go
+++ b/gremlin-go/driver/cucumber/gremlin.go
@@ -233,17 +233,14 @@ var translationMap = map[string][]func(g 
*gremlingo.GraphTraversalSource, p map[
     "g_V_valuesXdoubleX_isXtypeOfXGType_DOUBLEXX_order_byXascX": {func(g 
*gremlingo.GraphTraversalSource, p map[string]interface{}) 
*gremlingo.GraphTraversal {return g.AddV("data").Property("double", 
3.2).AddV("data").Property("double", 1.8).AddV("data").Property("double", 
2.5)}, func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) 
*gremlingo.GraphTraversal {return 
g.V().Values("double").Is(gremlingo.P.TypeOf(gremlingo.GType.Double)).Order().By(gremlingo.Order.Asc)}},
 
     "g_injectX5_5dX_isXtypeOfXGType_DOUBLEXX_groupCount": {func(g 
*gremlingo.GraphTraversalSource, p map[string]interface{}) 
*gremlingo.GraphTraversal {return 
g.Inject(5.5).Is(gremlingo.P.TypeOf(gremlingo.GType.Double)).GroupCount()}}, 
     "g_V_valuesXageX_isXtypeOfXGType_DOUBLEXX": {func(g 
*gremlingo.GraphTraversalSource, p map[string]interface{}) 
*gremlingo.GraphTraversal {return 
g.V().Values("age").Is(gremlingo.P.TypeOf(gremlingo.GType.Double))}}, 
-    "g_injectXDurationXPT2H30MXX": {func(g *gremlingo.GraphTraversalSource, p 
map[string]interface{}) *gremlingo.GraphTraversal {return 
g.Inject(time.Duration(9000000000000))}}, 
-    "g_injectXDurationXPT0SXX": {func(g *gremlingo.GraphTraversalSource, p 
map[string]interface{}) *gremlingo.GraphTraversal {return 
g.Inject(time.Duration(0))}}, 
-    "g_injectXDurationXPTneg30SXX": {func(g *gremlingo.GraphTraversalSource, p 
map[string]interface{}) *gremlingo.GraphTraversal {return 
g.Inject(time.Duration(-30000000000))}}, 
-    "g_injectXDurationXnegPT30SXX": {func(g *gremlingo.GraphTraversalSource, p 
map[string]interface{}) *gremlingo.GraphTraversal {return 
g.Inject(time.Duration(-30000000000))}}, 
-    "g_injectXDurationXPT0_5SXX": {func(g *gremlingo.GraphTraversalSource, p 
map[string]interface{}) *gremlingo.GraphTraversal {return 
g.Inject(time.Duration(500000000))}}, 
-    "g_injectXDurationXP1DT12HXX": {func(g *gremlingo.GraphTraversalSource, p 
map[string]interface{}) *gremlingo.GraphTraversal {return 
g.Inject(time.Duration(129600000000000))}}, 
-    "g_injectXDurationXP2DXX": {func(g *gremlingo.GraphTraversalSource, p 
map[string]interface{}) *gremlingo.GraphTraversal {return 
g.Inject(time.Duration(172800000000000))}}, 
-    "g_injectXDurationXPT1H30M15SXX": {func(g *gremlingo.GraphTraversalSource, 
p map[string]interface{}) *gremlingo.GraphTraversal {return 
g.Inject(time.Duration(5415000000000))}}, 
-    "g_injectXDurationXPTneg0_5SXX": {func(g *gremlingo.GraphTraversalSource, 
p map[string]interface{}) *gremlingo.GraphTraversal {return 
g.Inject(time.Duration(-500000000))}}, 
+    "g_injectXDurationX9000_0XX": {func(g *gremlingo.GraphTraversalSource, p 
map[string]interface{}) *gremlingo.GraphTraversal {return 
g.Inject(time.Duration(9000000000000))}}, 
+    "g_injectXDurationX0_0XX": {func(g *gremlingo.GraphTraversalSource, p 
map[string]interface{}) *gremlingo.GraphTraversal {return 
g.Inject(time.Duration(0))}}, 
+    "g_injectXDurationX0_500000000XX": {func(g 
*gremlingo.GraphTraversalSource, p map[string]interface{}) 
*gremlingo.GraphTraversal {return g.Inject(time.Duration(500000000))}}, 
+    "g_injectXDurationX30_0XX": {func(g *gremlingo.GraphTraversalSource, p 
map[string]interface{}) *gremlingo.GraphTraversal {return 
g.Inject(time.Duration(30000000000))}}, 
+    "g_injectXDurationX30_0_falseXX": {func(g *gremlingo.GraphTraversalSource, 
p map[string]interface{}) *gremlingo.GraphTraversal {return 
g.Inject(time.Duration(-30000000000))}}, 
+    "g_injectXDurationX1_500000000_falseXX": {func(g 
*gremlingo.GraphTraversalSource, p map[string]interface{}) 
*gremlingo.GraphTraversal {return g.Inject(time.Duration(-1500000000))}}, 
     "g_valuesXlengthX_isXtypeOfXGType_DURATIONXX": {func(g 
*gremlingo.GraphTraversalSource, p map[string]interface{}) 
*gremlingo.GraphTraversal {return g.AddV("data").Property("length", 
time.Duration(9000000000000))}, func(g *gremlingo.GraphTraversalSource, p 
map[string]interface{}) *gremlingo.GraphTraversal {return 
g.V().Values("length").Is(gremlingo.P.TypeOf(gremlingo.GType.Duration))}}, 
-    "g_injectXDurationXPT2H30MXX_isXgtXDurationXPT1HXXX": {func(g 
*gremlingo.GraphTraversalSource, p map[string]interface{}) 
*gremlingo.GraphTraversal {return 
g.Inject(time.Duration(9000000000000)).Is(gremlingo.P.Gt(time.Duration(3600000000000)))}},
 
+    "g_injectXDurationX9000_0XX_isXgtXDurationX3600_0XXX": {func(g 
*gremlingo.GraphTraversalSource, p map[string]interface{}) 
*gremlingo.GraphTraversal {return 
g.Inject(time.Duration(9000000000000)).Is(gremlingo.P.Gt(time.Duration(3600000000000)))}},
 
     "g_V_valuesXfloatX_isXtypeOfXGType_FLOATXX": {func(g 
*gremlingo.GraphTraversalSource, p map[string]interface{}) 
*gremlingo.GraphTraversal {return g.AddV("data").Property("float", 2.5)}, 
func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) 
*gremlingo.GraphTraversal {return 
g.V().Values("float").AsNumber(gremlingo.GType.Float).Is(gremlingo.P.TypeOf(gremlingo.GType.Float))}},
 
     "g_V_valuesXfloatX_isXtypeOfXGType_FLOATXX_mathXmulX2XX": {func(g 
*gremlingo.GraphTraversalSource, p map[string]interface{}) 
*gremlingo.GraphTraversal {return g.AddV("data").Property("float", 3.0)}, 
func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) 
*gremlingo.GraphTraversal {return 
g.V().Values("float").AsNumber(gremlingo.GType.Float).Is(gremlingo.P.TypeOf(gremlingo.GType.Float)).Math("_
 * 2")}}, 
     "g_V_valuesXfloatX_isXtypeOfXGType_FLOATXX_isXeqX1_5XX": {func(g 
*gremlingo.GraphTraversalSource, p map[string]interface{}) 
*gremlingo.GraphTraversal {return g.AddV("data").Property("float", 1.5)}, 
func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) 
*gremlingo.GraphTraversal {return 
g.V().Values("float").AsNumber(gremlingo.GType.Float).Is(gremlingo.P.TypeOf(gremlingo.GType.Float)).Is(gremlingo.P.Eq(1.5))}},
 
diff --git a/gremlin-go/driver/gremlinlang.go b/gremlin-go/driver/gremlinlang.go
index b063765f47..2362515e5f 100644
--- a/gremlin-go/driver/gremlinlang.go
+++ b/gremlin-go/driver/gremlinlang.go
@@ -137,54 +137,6 @@ func escapeString(s string) string {
        return sb.String()
 }
 
-// formatISO8601Duration formats a time.Duration as an ISO-8601 duration string
-// matching Java's Duration.toString() output (e.g., "PT2H30M", "PT-30S", 
"PT0.5S").
-func formatISO8601Duration(d time.Duration) string {
-       if d == 0 {
-               return "PT0S"
-       }
-
-       totalSeconds := int64(d / time.Second)
-       nanos := int64(d % time.Second)
-
-       hours := totalSeconds / 3600
-       minutes := (totalSeconds % 3600) / 60
-       seconds := totalSeconds % 60
-
-       var sb strings.Builder
-       sb.WriteString("PT")
-
-       if hours != 0 {
-               fmt.Fprintf(&sb, "%dH", hours)
-       }
-       if minutes != 0 {
-               fmt.Fprintf(&sb, "%dM", minutes)
-       }
-       if seconds != 0 || nanos != 0 {
-               if nanos == 0 {
-                       fmt.Fprintf(&sb, "%dS", seconds)
-               } else {
-                       absNanos := nanos
-                       if absNanos < 0 {
-                               absNanos = -absNanos
-                       }
-                       frac := fmt.Sprintf(".%09d", absNanos)
-                       frac = strings.TrimRight(frac, "0")
-                       // for negative sub-second durations where seconds 
truncated to 0
-                       if seconds == 0 && d < 0 {
-                               fmt.Fprintf(&sb, "-0%sS", frac)
-                       } else {
-                               fmt.Fprintf(&sb, "%d%sS", seconds, frac)
-                       }
-               }
-       }
-
-       if hours == 0 && minutes == 0 && seconds == 0 && nanos == 0 {
-               sb.WriteString("0S")
-       }
-
-       return sb.String()
-}
 
 func (gl *GremlinLang) argAsString(arg interface{}) (string, error) {
        if arg == nil {
@@ -320,7 +272,17 @@ func (gl *GremlinLang) argAsString(arg interface{}) 
(string, error) {
        case uuid.UUID:
                return fmt.Sprintf("UUID(\"%v\")", v.String()), nil
        case time.Duration:
-               return fmt.Sprintf("Duration(\"%s\")", 
formatISO8601Duration(v)), nil
+               isNegative := v < 0
+               abs := v
+               if isNegative {
+                       abs = -v
+               }
+               totalSeconds := int64(abs / time.Second)
+               nanos := int64(abs % time.Second)
+               if isNegative {
+                       return fmt.Sprintf("Duration(%d,%d,false)", 
totalSeconds, nanos), nil
+               }
+               return fmt.Sprintf("Duration(%d,%d)", totalSeconds, nanos), nil
        case ByteBuffer:
                return fmt.Sprintf("Binary(\"%s\")", 
base64.StdEncoding.EncodeToString(v.Data)), nil
        case *ByteBuffer:
diff --git a/gremlin-go/driver/gremlinlang_test.go 
b/gremlin-go/driver/gremlinlang_test.go
index 6e5f5d98cf..9d3ee5b93c 100644
--- a/gremlin-go/driver/gremlinlang_test.go
+++ b/gremlin-go/driver/gremlinlang_test.go
@@ -680,28 +680,6 @@ func Test_GremlinLang(t *testing.T) {
                        },
                        equals: 
"g.V().has(\"name\",\"\\\"marko\\n\\r\\t\\b\\f\\\"\")",
                },
-               // Duration - Go-specific: nanosecond precision, negative 
sub-second, days+hours normalization
-               {
-                       name: "g_Inject_Duration_NanosecondPrecision",
-                       assert: func(g *GraphTraversalSource) *GraphTraversal {
-                               return g.Inject(time.Nanosecond)
-                       },
-                       equals: `g.inject(Duration("PT0.000000001S"))`,
-               },
-               {
-                       name: "g_Inject_Duration_NegativeSubSecond",
-                       assert: func(g *GraphTraversalSource) *GraphTraversal {
-                               return g.Inject(-500 * time.Millisecond)
-                       },
-                       equals: `g.inject(Duration("PT-0.5S"))`,
-               },
-               {
-                       name: "g_Inject_Duration_DaysAndHours",
-                       assert: func(g *GraphTraversalSource) *GraphTraversal {
-                               return g.Inject(36 * time.Hour)
-                       },
-                       equals: `g.inject(Duration("PT36H"))`,
-               },
                // Binary - []byte type (distinct from ByteBuffer)
                {
                        name: "g_Inject_ByteSlice",
diff --git 
a/gremlin-js/gremlin-javascript/lib/language/translator/DotNetTranslateVisitor.ts
 
b/gremlin-js/gremlin-javascript/lib/language/translator/DotNetTranslateVisitor.ts
index a497573696..8cb11b125b 100644
--- 
a/gremlin-js/gremlin-javascript/lib/language/translator/DotNetTranslateVisitor.ts
+++ 
b/gremlin-js/gremlin-javascript/lib/language/translator/DotNetTranslateVisitor.ts
@@ -235,33 +235,16 @@ export default class DotNetTranslateVisitor extends 
TranslateVisitor {
     }
 
     visitDurationLiteral(ctx: any): void {
-        const iso8601 = 
TranslateVisitor.removeFirstAndLastCharacters(ctx.stringLiteral().getText());
-        // .NET's XmlConvert.ToTimeSpan requires "-PT30S" not "PT-30S", so 
parse and
-        // re-emit in the normalized form that .NET expects
-        const { totalSeconds, nanos } = parseDurationComponents(iso8601);
-        // combine into total nanos for correct decomposition
-        const totalNanos = totalSeconds * 1_000_000_000 + nanos;
-        const isNegative = totalNanos < 0;
-        const absNanos = Math.abs(totalNanos);
-        const absSec = Math.floor(absNanos / 1_000_000_000);
-        const fracNanos = absNanos % 1_000_000_000;
-        const hours = Math.floor(absSec / 3600);
-        const minutes = Math.floor((absSec % 3600) / 60);
-        const seconds = absSec % 60;
-        let normalized = 'PT';
-        if (hours !== 0) normalized += `${hours}H`;
-        if (minutes !== 0) normalized += `${minutes}M`;
-        if (seconds !== 0 || fracNanos !== 0) {
-            if (fracNanos === 0) {
-                normalized += `${seconds}S`;
-            } else {
-                const frac = fracNanos.toString().padStart(9, 
'0').replace(/0+$/, '');
-                normalized += `${seconds}.${frac}S`;
-            }
+        const seconds = parseInt(ctx.integerLiteral(0).getText(), 10);
+        const nanos = parseInt(ctx.integerLiteral(1).getText(), 10);
+        const isPositive = ctx.booleanLiteral() === null ||
+            ctx.booleanLiteral().getText() === 'true';
+        // Convert to ticks: 1 tick = 100 nanoseconds, 1 second = 10,000,000 
ticks
+        const ticks = seconds * 10_000_000 + Math.floor(nanos / 100);
+        this.sb.push(`TimeSpan.FromTicks(${ticks}L)`);
+        if (!isPositive) {
+            this.sb.push('.Negate()');
         }
-        if (normalized === 'PT') normalized = 'PT0S';
-        if (isNegative) normalized = '-' + normalized;
-        this.sb.push(`XmlConvert.ToTimeSpan("${normalized}")`);
     }
 
     visitBinaryLiteral(ctx: any): void {
@@ -890,48 +873,6 @@ function capitalize(s: string): string {
     return s.charAt(0).toUpperCase() + s.slice(1);
 }
 
-/**
- * Parses an ISO-8601 duration string into total seconds and nanoseconds,
- * normalizing so nanos is always 0..999999999 (matching Java's Duration).
- */
-function parseDurationComponents(iso8601: string): { totalSeconds: number; 
nanos: number } {
-    const match = 
iso8601.match(/^([+-]?)P(?:(\d+)D)?T?(?:([+-]?\d+)H)?(?:([+-]?\d+)M)?(?:([+-]?\d+(?:\.\d+)?)S)?$/);
-    if (!match) {
-        throw new TranslatorException(`Invalid ISO-8601 duration: ${iso8601}`);
-    }
-    const negative = match[1] === '-';
-    const days = match[2] ? parseInt(match[2], 10) : 0;
-    const hours = match[3] ? parseInt(match[3], 10) : 0;
-    const minutes = match[4] ? parseInt(match[4], 10) : 0;
-
-    let totalSeconds = days * 86400 + hours * 3600 + minutes * 60;
-    let nanos = 0;
-
-    if (match[5]) {
-        const secParts = match[5].split('.');
-        totalSeconds += parseInt(secParts[0], 10);
-        if (secParts.length > 1) {
-            nanos = parseInt(secParts[1].padEnd(9, '0').substring(0, 9), 10);
-            if (parseInt(secParts[0], 10) < 0 || (parseInt(secParts[0], 10) 
=== 0 && match[5].startsWith('-'))) {
-                nanos = -nanos;
-            }
-        }
-    }
-
-    if (negative) {
-        totalSeconds = -totalSeconds;
-        nanos = -nanos;
-    }
-
-    // Normalize so nanos is always 0..999999999 (matching Java's Duration)
-    if (nanos < 0) {
-        totalSeconds -= 1;
-        nanos += 1_000_000_000;
-    }
-
-    return { totalSeconds, nanos };
-}
-
 /**
  * Formats a datetime string the same way Java's OffsetDateTime.toString() 
does:
  * - Truncates seconds if both seconds and milliseconds are 0
diff --git 
a/gremlin-js/gremlin-javascript/lib/language/translator/GoTranslateVisitor.ts 
b/gremlin-js/gremlin-javascript/lib/language/translator/GoTranslateVisitor.ts
index 0b168d00d8..c95cc6de32 100644
--- 
a/gremlin-js/gremlin-javascript/lib/language/translator/GoTranslateVisitor.ts
+++ 
b/gremlin-js/gremlin-javascript/lib/language/translator/GoTranslateVisitor.ts
@@ -262,9 +262,13 @@ export default class GoTranslateVisitor extends 
TranslateVisitor {
     }
 
     visitDurationLiteral(ctx: any): void {
-        const iso8601 = 
TranslateVisitor.removeFirstAndLastCharacters(ctx.stringLiteral().getText());
-        const nanos = parseISO8601DurationToNanos(iso8601);
-        this.sb.push(`time.Duration(${nanos})`);
+        const seconds = parseInt(ctx.integerLiteral(0).getText(), 10);
+        const nanos = parseInt(ctx.integerLiteral(1).getText(), 10);
+        const isPositive = ctx.booleanLiteral() === null ||
+            ctx.booleanLiteral().getText() === 'true';
+        // Use BigInt to avoid precision loss for durations over ~104 days
+        const totalNanos = BigInt(seconds) * 1_000_000_000n + BigInt(nanos);
+        this.sb.push(`time.Duration(${isPositive ? totalNanos : 
-totalNanos})`);
     }
 
     visitBinaryLiteral(ctx: any): void {
@@ -371,38 +375,6 @@ export default class GoTranslateVisitor extends 
TranslateVisitor {
     }
 }
 
-/**
- * Parses an ISO-8601 duration string into total nanoseconds,
- * matching the Java GoTranslateVisitor behavior.
- */
-function parseISO8601DurationToNanos(iso8601: string): number {
-    const match = 
iso8601.match(/^([+-]?)P(?:(\d+)D)?T?(?:([+-]?\d+)H)?(?:([+-]?\d+)M)?(?:([+-]?\d+(?:\.\d+)?)S)?$/);
-    if (!match) {
-        throw new TranslatorException(`Invalid ISO-8601 duration: ${iso8601}`);
-    }
-    const negative = match[1] === '-';
-    const days = match[2] ? parseInt(match[2], 10) : 0;
-    const hours = match[3] ? parseInt(match[3], 10) : 0;
-    const minutes = match[4] ? parseInt(match[4], 10) : 0;
-
-    let totalNanos = (days * 86400 + hours * 3600 + minutes * 60) * 
1_000_000_000;
-
-    if (match[5]) {
-        const secParts = match[5].split('.');
-        totalNanos += parseInt(secParts[0], 10) * 1_000_000_000;
-        if (secParts.length > 1) {
-            const fracStr = secParts[1].padEnd(9, '0').substring(0, 9);
-            let fracNanos = parseInt(fracStr, 10);
-            if (parseInt(secParts[0], 10) < 0 || (parseInt(secParts[0], 10) 
=== 0 && match[5].startsWith('-'))) {
-                fracNanos = -fracNanos;
-            }
-            totalNanos += fracNanos;
-        }
-    }
-
-    return negative ? -totalNanos : totalNanos;
-}
-
 /**
  * Decodes a base64 string into an array of unsigned byte values.
  */
diff --git 
a/gremlin-js/gremlin-javascript/lib/language/translator/GroovyTranslateVisitor.ts
 
b/gremlin-js/gremlin-javascript/lib/language/translator/GroovyTranslateVisitor.ts
index d77946da39..f061975e2b 100644
--- 
a/gremlin-js/gremlin-javascript/lib/language/translator/GroovyTranslateVisitor.ts
+++ 
b/gremlin-js/gremlin-javascript/lib/language/translator/GroovyTranslateVisitor.ts
@@ -124,9 +124,14 @@ export default class GroovyTranslateVisitor extends 
TranslateVisitor {
     }
 
     visitDurationLiteral(ctx: any): void {
-        this.sb.push('Duration.parse(');
-        this.sb.push(ctx.stringLiteral().getText());
-        this.sb.push(')');
+        const seconds = parseInt(ctx.integerLiteral(0).getText(), 10);
+        const nanos = parseInt(ctx.integerLiteral(1).getText(), 10);
+        const isPositive = ctx.booleanLiteral() === null ||
+            ctx.booleanLiteral().getText() === 'true';
+        this.sb.push(`Duration.ofSeconds(${seconds}, ${nanos})`);
+        if (!isPositive) {
+            this.sb.push('.negated()');
+        }
     }
 
     visitBinaryLiteral(ctx: any): void {
diff --git 
a/gremlin-js/gremlin-javascript/lib/language/translator/JavaTranslateVisitor.ts 
b/gremlin-js/gremlin-javascript/lib/language/translator/JavaTranslateVisitor.ts
index 414b76b6aa..fbbe38d1b1 100644
--- 
a/gremlin-js/gremlin-javascript/lib/language/translator/JavaTranslateVisitor.ts
+++ 
b/gremlin-js/gremlin-javascript/lib/language/translator/JavaTranslateVisitor.ts
@@ -210,9 +210,14 @@ export default class JavaTranslateVisitor extends 
TranslateVisitor {
     }
 
     visitDurationLiteral(ctx: any): void {
-        this.sb.push('Duration.parse(');
-        this.sb.push(ctx.stringLiteral().getText());
-        this.sb.push(')');
+        const seconds = parseInt(ctx.integerLiteral(0).getText(), 10);
+        const nanos = parseInt(ctx.integerLiteral(1).getText(), 10);
+        const isPositive = ctx.booleanLiteral() === null ||
+            ctx.booleanLiteral().getText() === 'true';
+        this.sb.push(`Duration.ofSeconds(${seconds}, ${nanos})`);
+        if (!isPositive) {
+            this.sb.push('.negated()');
+        }
     }
 
     visitBinaryLiteral(ctx: any): void {
diff --git 
a/gremlin-js/gremlin-javascript/lib/language/translator/PythonTranslateVisitor.ts
 
b/gremlin-js/gremlin-javascript/lib/language/translator/PythonTranslateVisitor.ts
index 9be9365804..e9e4de9967 100644
--- 
a/gremlin-js/gremlin-javascript/lib/language/translator/PythonTranslateVisitor.ts
+++ 
b/gremlin-js/gremlin-javascript/lib/language/translator/PythonTranslateVisitor.ts
@@ -224,13 +224,18 @@ export default class PythonTranslateVisitor extends 
TranslateVisitor {
     }
 
     visitDurationLiteral(ctx: any): void {
-        const iso8601 = 
TranslateVisitor.removeFirstAndLastCharacters(ctx.stringLiteral().getText());
-        const { totalSeconds, nanos } = parseISO8601Duration(iso8601);
-        if (nanos === 0) {
+        const seconds = parseInt(ctx.integerLiteral(0).getText(), 10);
+        const nanos = parseInt(ctx.integerLiteral(1).getText(), 10);
+        const isPositive = ctx.booleanLiteral() === null ||
+            ctx.booleanLiteral().getText() === 'true';
+        const totalSeconds = isPositive ? seconds : -seconds;
+        // Python's timedelta has microsecond resolution; sub-microsecond 
nanos are truncated
+        const micros = Math.floor(nanos / 1000);
+        if (micros === 0) {
             this.sb.push(`timedelta(seconds=${totalSeconds})`);
         } else {
-            const micros = Math.floor(nanos / 1000);
-            
this.sb.push(`timedelta(seconds=${totalSeconds},microseconds=${micros})`);
+            const totalMicros = isPositive ? micros : -micros;
+            
this.sb.push(`timedelta(seconds=${totalSeconds},microseconds=${totalMicros})`);
         }
     }
 
@@ -346,45 +351,4 @@ function convertCamelCaseToSnakeCase(camelCase: string): 
string {
     return result;
 }
 
-/**
- * Parses an ISO-8601 duration string (as produced by Java's 
Duration.toString())
- * into total seconds and nanoseconds, matching the Java 
PythonTranslateVisitor behavior.
- */
-function parseISO8601Duration(iso8601: string): { totalSeconds: number; nanos: 
number } {
-    // Use a regex that matches Java's Duration.toString() output
-    const match = 
iso8601.match(/^([+-]?)P(?:(\d+)D)?T?(?:([+-]?\d+)H)?(?:([+-]?\d+)M)?(?:([+-]?\d+(?:\.\d+)?)S)?$/);
-    if (!match) {
-        throw new TranslatorException(`Invalid ISO-8601 duration: ${iso8601}`);
-    }
-    const negative = match[1] === '-';
-    const days = match[2] ? parseInt(match[2], 10) : 0;
-    const hours = match[3] ? parseInt(match[3], 10) : 0;
-    const minutes = match[4] ? parseInt(match[4], 10) : 0;
-
-    let totalSeconds = days * 86400 + hours * 3600 + minutes * 60;
-    let nanos = 0;
-
-    if (match[5]) {
-        const secParts = match[5].split('.');
-        totalSeconds += parseInt(secParts[0], 10);
-        if (secParts.length > 1) {
-            nanos = parseInt(secParts[1].padEnd(9, '0').substring(0, 9), 10);
-            if (parseInt(secParts[0], 10) < 0 || (parseInt(secParts[0], 10) 
=== 0 && match[5].startsWith('-'))) {
-                nanos = -nanos;
-            }
-        }
-    }
 
-    if (negative) {
-        totalSeconds = -totalSeconds;
-        nanos = -nanos;
-    }
-
-    // Normalize so nanos is always 0..999999999 (matching Java's Duration 
representation)
-    if (nanos < 0) {
-        totalSeconds -= 1;
-        nanos += 1_000_000_000;
-    }
-
-    return { totalSeconds, nanos };
-}
diff --git a/gremlin-js/gremlin-javascript/test/cucumber/gremlin.js 
b/gremlin-js/gremlin-javascript/test/cucumber/gremlin.js
index 5338791541..2b0adf72b4 100644
--- a/gremlin-js/gremlin-javascript/test/cucumber/gremlin.js
+++ b/gremlin-js/gremlin-javascript/test/cucumber/gremlin.js
@@ -265,17 +265,14 @@ const gremlins = {
     g_V_valuesXdoubleX_isXtypeOfXGType_DOUBLEXX_order_byXascX: [function({g}) 
{ return g.addV("data").property("double", 3.2).addV("data").property("double", 
1.8).addV("data").property("double", 2.5) }, function({g}) { return 
g.V().values("double").is(P.typeOf(GType.double)).order().by(Order.asc) }], 
     g_injectX5_5dX_isXtypeOfXGType_DOUBLEXX_groupCount: [function({g}) { 
return g.inject(5.5).is(P.typeOf(GType.double)).groupCount() }], 
     g_V_valuesXageX_isXtypeOfXGType_DOUBLEXX: [function({g}) { return 
g.V().values("age").is(P.typeOf(GType.double)) }], 
-    g_injectXDurationXPT2H30MXX: [function({g}) { return null }], 
-    g_injectXDurationXPT0SXX: [function({g}) { return null }], 
-    g_injectXDurationXPTneg30SXX: [function({g}) { return null }], 
-    g_injectXDurationXnegPT30SXX: [function({g}) { return null }], 
-    g_injectXDurationXPT0_5SXX: [function({g}) { return null }], 
-    g_injectXDurationXP1DT12HXX: [function({g}) { return null }], 
-    g_injectXDurationXP2DXX: [function({g}) { return null }], 
-    g_injectXDurationXPT1H30M15SXX: [function({g}) { return null }], 
-    g_injectXDurationXPTneg0_5SXX: [function({g}) { return null }], 
+    g_injectXDurationX9000_0XX: [function({g}) { return null }], 
+    g_injectXDurationX0_0XX: [function({g}) { return null }], 
+    g_injectXDurationX0_500000000XX: [function({g}) { return null }], 
+    g_injectXDurationX30_0XX: [function({g}) { return null }], 
+    g_injectXDurationX30_0_falseXX: [function({g}) { return null }], 
+    g_injectXDurationX1_500000000_falseXX: [function({g}) { return null }], 
     g_valuesXlengthX_isXtypeOfXGType_DURATIONXX: [function({g}) { return null 
}], 
-    g_injectXDurationXPT2H30MXX_isXgtXDurationXPT1HXXX: [function({g}) { 
return null }], 
+    g_injectXDurationX9000_0XX_isXgtXDurationX3600_0XXX: [function({g}) { 
return null }], 
     g_V_valuesXfloatX_isXtypeOfXGType_FLOATXX: [function({g}) { return 
g.addV("data").property("float", 2.5) }, function({g}) { return 
g.V().values("float").asNumber(GType.float).is(P.typeOf(GType.float)) }], 
     g_V_valuesXfloatX_isXtypeOfXGType_FLOATXX_mathXmulX2XX: [function({g}) { 
return g.addV("data").property("float", 3.0) }, function({g}) { return 
g.V().values("float").asNumber(GType.float).is(P.typeOf(GType.float)).math("_ * 
2") }], 
     g_V_valuesXfloatX_isXtypeOfXGType_FLOATXX_isXeqX1_5XX: [function({g}) { 
return g.addV("data").property("float", 1.5) }, function({g}) { return 
g.V().values("float").asNumber(GType.float).is(P.typeOf(GType.float)).is(P.eq(1.5))
 }], 
diff --git a/gremlin-language/src/main/antlr4/Gremlin.g4 
b/gremlin-language/src/main/antlr4/Gremlin.g4
index 68b1fc58c8..6798ebde55 100644
--- a/gremlin-language/src/main/antlr4/Gremlin.g4
+++ b/gremlin-language/src/main/antlr4/Gremlin.g4
@@ -1721,7 +1721,7 @@ characterLiteral
     ;
 
 durationLiteral
-    : K_DURATIONC LPAREN stringLiteral RPAREN
+    : K_DURATIONC LPAREN integerLiteral COMMA integerLiteral (COMMA 
booleanLiteral)? RPAREN
     ;
 
 binaryLiteral
diff --git a/gremlin-python/src/main/python/gremlin_python/process/traversal.py 
b/gremlin-python/src/main/python/gremlin_python/process/traversal.py
index 41ec218a36..4a531d5845 100644
--- a/gremlin-python/src/main/python/gremlin_python/process/traversal.py
+++ b/gremlin-python/src/main/python/gremlin_python/process/traversal.py
@@ -805,44 +805,6 @@ GREMLIN LANGUAGE
 '''
 
 
-def _format_iso8601_duration(td):
-    """Formats a timedelta as an ISO-8601 duration string matching Java's 
Duration.toString()."""
-    if td == timedelta(0):
-        return "PT0S"
-
-    total_seconds = int(td.total_seconds())
-    microseconds = td.microseconds if td.total_seconds() >= 0 else 
-td.microseconds
-
-    # detect negative sub-second durations where int() truncates to 0
-    is_negative = td.total_seconds() < 0
-
-    # use int() for truncation toward zero (not // which is floor division in 
Python)
-    hours = int(total_seconds / 3600)
-    minutes = int((total_seconds - hours * 3600) / 60)
-    seconds = total_seconds - hours * 3600 - minutes * 60
-
-    parts = ["PT"]
-    if hours != 0:
-        parts.append(f"{hours}H")
-    if minutes != 0:
-        parts.append(f"{minutes}M")
-    if seconds != 0 or microseconds != 0:
-        if microseconds == 0:
-            parts.append(f"{seconds}S")
-        else:
-            frac = abs(microseconds) / 1_000_000
-            frac_str = f"{frac:.6f}".lstrip("0").rstrip("0")
-            # for negative sub-second durations where seconds truncated to 0
-            if seconds == 0 and is_negative:
-                parts.append(f"-0{frac_str}S")
-            else:
-                parts.append(f"{seconds}{frac_str}S")
-    if len(parts) == 1:
-        parts.append("0S")
-
-    return "".join(parts)
-
-
 class GremlinLang(object):
     conn_p = ['and', 'or']
 
@@ -922,7 +884,15 @@ class GremlinLang(object):
             return f'UUID("{arg}")'
 
         if isinstance(arg, timedelta):
-            return f'Duration("{_format_iso8601_duration(arg)}")'
+            is_negative = arg.total_seconds() < 0
+            abs_td = -arg if is_negative else arg
+            # Use integer components directly to avoid float precision loss
+            seconds = abs_td.days * 86400 + abs_td.seconds
+            nanos = abs_td.microseconds * 1000
+            if is_negative:
+                return f'Duration({seconds},{nanos},false)'
+            else:
+                return f'Duration({seconds},{nanos})'
 
         if isinstance(arg, bytes):
             return f'Binary("{base64.b64encode(arg).decode("ascii")}")'
diff --git a/gremlin-python/src/main/python/tests/feature/feature_steps.py 
b/gremlin-python/src/main/python/tests/feature/feature_steps.py
index 7ed183413c..c5365d009f 100644
--- a/gremlin-python/src/main/python/tests/feature/feature_steps.py
+++ b/gremlin-python/src/main/python/tests/feature/feature_steps.py
@@ -346,16 +346,15 @@ def _split_by_element(s):
     return results
 
 
-def _parse_iso8601_duration(iso_str):
-    """Parses an ISO-8601 duration string (as produced by Java's 
Duration.toString()) into a timedelta."""
-    m = re.match(r'^(-?)PT(?:(-?\d+)H)?(?:(-?\d+)M)?(?:(-?\d+(?:\.\d+)?)S)?$', 
iso_str)
-    if not m:
-        raise ValueError("Invalid ISO-8601 duration: " + iso_str)
-    sign = -1 if m.group(1) == '-' else 1
-    hours = int(m.group(2)) if m.group(2) else 0
-    minutes = int(m.group(3)) if m.group(3) else 0
-    seconds = float(m.group(4)) if m.group(4) else 0.0
-    return timedelta(hours=sign * hours, minutes=sign * minutes, seconds=sign 
* seconds)
+def _parse_duration(dur_str):
+    """Parses a duration from seconds,nanos[,isPositive] format into a 
timedelta."""
+    parts = dur_str.split(",")
+    seconds = int(parts[0].strip())
+    nanos = int(parts[1].strip())
+    is_positive = len(parts) < 3 or parts[2].strip() == "true"
+    # timedelta has microsecond resolution; sub-microsecond nanos are truncated
+    td = timedelta(seconds=seconds, microseconds=nanos // 1000)
+    return td if is_positive else -td
 
 
 def _convert(val, ctx):
@@ -382,7 +381,7 @@ def _convert(val, ctx):
     elif isinstance(val, str) and re.match(r"^char\[.\]$", val):  # parse char
         return SingleChar(val[5:-1])
     elif isinstance(val, str) and re.match(r"^dur\[.*\]$", val):  # parse 
duration
-        return _parse_iso8601_duration(val[4:-1])
+        return _parse_duration(val[4:-1])
     elif isinstance(val, str) and re.match(r"^bin\[.*\]$", val):  # parse 
binary
         return base64.b64decode(val[4:-1])
     elif isinstance(val, str) and re.match(r"^d\[NaN\]$", val):  # parse nan
diff --git a/gremlin-python/src/main/python/tests/feature/gremlin.py 
b/gremlin-python/src/main/python/tests/feature/gremlin.py
index e2854391a4..9cd84e34ff 100644
--- a/gremlin-python/src/main/python/tests/feature/gremlin.py
+++ b/gremlin-python/src/main/python/tests/feature/gremlin.py
@@ -238,17 +238,14 @@ world.gremlins = {
     'g_V_valuesXdoubleX_isXtypeOfXGType_DOUBLEXX_order_byXascX': [(lambda 
g:g.add_v('data').property('double', 3.2).add_v('data').property('double', 
1.8).add_v('data').property('double', 2.5)), (lambda 
g:g.V().values('double').is_(P.type_of(GType.DOUBLE)).order().by(Order.asc))], 
     'g_injectX5_5dX_isXtypeOfXGType_DOUBLEXX_groupCount': [(lambda 
g:g.inject(5.5).is_(P.type_of(GType.DOUBLE)).group_count())], 
     'g_V_valuesXageX_isXtypeOfXGType_DOUBLEXX': [(lambda 
g:g.V().values('age').is_(P.type_of(GType.DOUBLE)))], 
-    'g_injectXDurationXPT2H30MXX': [(lambda 
g:g.inject(timedelta(seconds=9000)))], 
-    'g_injectXDurationXPT0SXX': [(lambda g:g.inject(timedelta(seconds=0)))], 
-    'g_injectXDurationXPTneg30SXX': [(lambda 
g:g.inject(timedelta(seconds=-30)))], 
-    'g_injectXDurationXnegPT30SXX': [(lambda 
g:g.inject(timedelta(seconds=-30)))], 
-    'g_injectXDurationXPT0_5SXX': [(lambda 
g:g.inject(timedelta(seconds=0,microseconds=500000)))], 
-    'g_injectXDurationXP1DT12HXX': [(lambda 
g:g.inject(timedelta(seconds=129600)))], 
-    'g_injectXDurationXP2DXX': [(lambda 
g:g.inject(timedelta(seconds=172800)))], 
-    'g_injectXDurationXPT1H30M15SXX': [(lambda 
g:g.inject(timedelta(seconds=5415)))], 
-    'g_injectXDurationXPTneg0_5SXX': [(lambda 
g:g.inject(timedelta(seconds=-1,microseconds=500000)))], 
+    'g_injectXDurationX9000_0XX': [(lambda 
g:g.inject(timedelta(seconds=9000)))], 
+    'g_injectXDurationX0_0XX': [(lambda g:g.inject(timedelta(seconds=0)))], 
+    'g_injectXDurationX0_500000000XX': [(lambda 
g:g.inject(timedelta(seconds=0,microseconds=500000)))], 
+    'g_injectXDurationX30_0XX': [(lambda g:g.inject(timedelta(seconds=30)))], 
+    'g_injectXDurationX30_0_falseXX': [(lambda 
g:g.inject(timedelta(seconds=-30)))], 
+    'g_injectXDurationX1_500000000_falseXX': [(lambda 
g:g.inject(timedelta(seconds=-1,microseconds=-500000)))], 
     'g_valuesXlengthX_isXtypeOfXGType_DURATIONXX': [(lambda 
g:g.add_v('data').property('length', timedelta(seconds=9000))), (lambda 
g:g.V().values('length').is_(P.type_of(GType.DURATION)))], 
-    'g_injectXDurationXPT2H30MXX_isXgtXDurationXPT1HXXX': [(lambda 
g:g.inject(timedelta(seconds=9000)).is_(P.gt(timedelta(seconds=3600))))], 
+    'g_injectXDurationX9000_0XX_isXgtXDurationX3600_0XXX': [(lambda 
g:g.inject(timedelta(seconds=9000)).is_(P.gt(timedelta(seconds=3600))))], 
     'g_V_valuesXfloatX_isXtypeOfXGType_FLOATXX': [(lambda 
g:g.add_v('data').property('float', 2.5)), (lambda 
g:g.V().values('float').as_number(GType.FLOAT).is_(P.type_of(GType.FLOAT)))], 
     'g_V_valuesXfloatX_isXtypeOfXGType_FLOATXX_mathXmulX2XX': [(lambda 
g:g.add_v('data').property('float', 3.0)), (lambda 
g:g.V().values('float').as_number(GType.FLOAT).is_(P.type_of(GType.FLOAT)).math('_
 * 2'))], 
     'g_V_valuesXfloatX_isXtypeOfXGType_FLOATXX_isXeqX1_5XX': [(lambda 
g:g.add_v('data').property('float', 1.5)), (lambda 
g:g.V().values('float').as_number(GType.FLOAT).is_(P.type_of(GType.FLOAT)).is_(P.eq(1.5)))],
 
diff --git 
a/gremlin-python/src/main/python/tests/unit/process/test_gremlin_lang.py 
b/gremlin-python/src/main/python/tests/unit/process/test_gremlin_lang.py
index 7abfc2fa31..0f1351e8c1 100644
--- a/gremlin-python/src/main/python/tests/unit/process/test_gremlin_lang.py
+++ b/gremlin-python/src/main/python/tests/unit/process/test_gremlin_lang.py
@@ -492,14 +492,6 @@ class TestGremlinLang(object):
         tests.append([g.inject(SingleChar("'")),
                       "g.inject(\"'\"c)"])
 
-        # Duration - Python-specific: microsecond precision, days+hours 
normalization
-        # 124
-        tests.append([g.inject(timedelta(microseconds=1)),
-                      'g.inject(Duration("PT0.000001S"))'])
-        # 125
-        tests.append([g.inject(timedelta(days=1, hours=12)),
-                      'g.inject(Duration("PT36H"))'])
-
         for t in range(len(tests)):
             gremlin_lang = tests[t][0].gremlin_lang.get_gremlin()
             assert gremlin_lang == tests[t][1]
diff --git 
a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/features/StepDefinition.java
 
b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/features/StepDefinition.java
index 208db90d46..45f29c17b6 100644
--- 
a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/features/StepDefinition.java
+++ 
b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/features/StepDefinition.java
@@ -169,7 +169,13 @@ public final class StepDefinition {
         add(Pair.with(Pattern.compile("dt\\[(.*)\\]"), s -> 
String.format("datetime('%s')", s)));
 
         add(Pair.with(Pattern.compile("char\\[(.)\\]"), s -> 
String.format("\"%s\"c", s)));
-        add(Pair.with(Pattern.compile("dur\\[(.*)\\]"), s -> 
String.format("Duration(\"%s\")", s)));
+        add(Pair.with(Pattern.compile("dur\\[(.*)\\]"), s -> {
+            final String[] parts = s.split(",");
+            if (parts.length == 2)
+                return String.format("Duration(%s, %s)", parts[0].trim(), 
parts[1].trim());
+            else
+                return String.format("Duration(%s, %s, %s)", parts[0].trim(), 
parts[1].trim(), parts[2].trim());
+        }));
         add(Pair.with(Pattern.compile("bin\\[(.*)\\]"), s -> 
String.format("Binary(\"%s\")", s)));
 
         add(Pair.with(Pattern.compile("v\\[(.+)\\]\\.id"), s -> 
world.convertIdToScript(g.V().has("name", s).id().next(), Vertex.class)));
@@ -245,7 +251,14 @@ public final class StepDefinition {
         add(Pair.with(Pattern.compile("uuid\\[(.*)\\]"), UUID::fromString));
 
         add(Pair.with(Pattern.compile("char\\[(.)\\]"), s -> s.charAt(0)));
-        add(Pair.with(Pattern.compile("dur\\[(.*)\\]"), s -> 
Duration.parse(s)));
+        add(Pair.with(Pattern.compile("dur\\[(.*)\\]"), s -> {
+            final String[] parts = s.split(",");
+            final long seconds = Long.parseLong(parts[0].trim());
+            final int nanos = Integer.parseInt(parts[1].trim());
+            final boolean isPositive = parts.length < 3 || 
Boolean.parseBoolean(parts[2].trim());
+            final Duration d = Duration.ofSeconds(seconds, nanos);
+            return isPositive ? d : d.negated();
+        }));
         add(Pair.with(Pattern.compile("bin\\[(.*)\\]"), s -> 
ByteBuffer.wrap(Base64.getDecoder().decode(s))));
 
         add(Pair.with(Pattern.compile("v\\[(.+)\\]\\.id"), s -> 
g.V().has("name", s).id().next()));
diff --git 
a/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/language/translator/translations.json
 
b/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/language/translator/translations.json
index 6d5fd5e158..44163ea0f7 100644
--- 
a/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/language/translator/translations.json
+++ 
b/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/language/translator/translations.json
@@ -3894,146 +3894,98 @@
         ]
     },
     {
-        "scenario": "g_injectXDurationXPT2H30MXX",
+        "scenario": "g_injectXDurationX9000_0XX",
         "traversals": [
             {
-                "original": "g.inject(Duration(\"PT2H30M\"))",
-                "language": "g.inject(Duration(\"PT2H30M\"))",
-                "canonical": "g.inject(Duration(\"PT2H30M\"))",
+                "original": "g.inject(Duration(9000, 0))",
+                "language": "g.inject(Duration(9000,0))",
+                "canonical": "g.inject(Duration(9000,0))",
                 "anonymized": "g.inject(duration0)",
-                "dotnet": 
"g.Inject<object>(XmlConvert.ToTimeSpan(\"PT2H30M\"))",
+                "dotnet": "g.Inject<object>(TimeSpan.FromTicks(90000000000L))",
                 "go": "g.Inject(time.Duration(9000000000000))",
-                "groovy": "g.inject(Duration.parse(\"PT2H30M\"))",
-                "java": "g.inject(Duration.parse(\"PT2H30M\"))",
+                "groovy": "g.inject(Duration.ofSeconds(9000, 0))",
+                "java": "g.inject(Duration.ofSeconds(9000, 0))",
                 "python": "g.inject(timedelta(seconds=9000))"
             }
         ]
     },
     {
-        "scenario": "g_injectXDurationXPT0SXX",
+        "scenario": "g_injectXDurationX0_0XX",
         "traversals": [
             {
-                "original": "g.inject(Duration(\"PT0S\"))",
-                "language": "g.inject(Duration(\"PT0S\"))",
-                "canonical": "g.inject(Duration(\"PT0S\"))",
+                "original": "g.inject(Duration(0, 0))",
+                "language": "g.inject(Duration(0,0))",
+                "canonical": "g.inject(Duration(0,0))",
                 "anonymized": "g.inject(duration0)",
-                "dotnet": "g.Inject<object>(XmlConvert.ToTimeSpan(\"PT0S\"))",
+                "dotnet": "g.Inject<object>(TimeSpan.FromTicks(0L))",
                 "go": "g.Inject(time.Duration(0))",
-                "groovy": "g.inject(Duration.parse(\"PT0S\"))",
-                "java": "g.inject(Duration.parse(\"PT0S\"))",
+                "groovy": "g.inject(Duration.ofSeconds(0, 0))",
+                "java": "g.inject(Duration.ofSeconds(0, 0))",
                 "python": "g.inject(timedelta(seconds=0))"
             }
         ]
     },
     {
-        "scenario": "g_injectXDurationXPTneg30SXX",
+        "scenario": "g_injectXDurationX0_500000000XX",
         "traversals": [
             {
-                "original": "g.inject(Duration(\"PT-30S\"))",
-                "language": "g.inject(Duration(\"PT-30S\"))",
-                "canonical": "g.inject(Duration(\"PT-30S\"))",
+                "original": "g.inject(Duration(0, 500000000))",
+                "language": "g.inject(Duration(0,500000000))",
+                "canonical": "g.inject(Duration(0,500000000))",
                 "anonymized": "g.inject(duration0)",
-                "dotnet": 
"g.Inject<object>(XmlConvert.ToTimeSpan(\"-PT30S\"))",
-                "go": "g.Inject(time.Duration(-30000000000))",
-                "groovy": "g.inject(Duration.parse(\"PT-30S\"))",
-                "java": "g.inject(Duration.parse(\"PT-30S\"))",
-                "python": "g.inject(timedelta(seconds=-30))"
-            }
-        ]
-    },
-    {
-        "scenario": "g_injectXDurationXnegPT30SXX",
-        "traversals": [
-            {
-                "original": "g.inject(Duration(\"-PT30S\"))",
-                "language": "g.inject(Duration(\"-PT30S\"))",
-                "canonical": "g.inject(Duration(\"-PT30S\"))",
-                "anonymized": "g.inject(duration0)",
-                "dotnet": 
"g.Inject<object>(XmlConvert.ToTimeSpan(\"-PT30S\"))",
-                "go": "g.Inject(time.Duration(-30000000000))",
-                "groovy": "g.inject(Duration.parse(\"-PT30S\"))",
-                "java": "g.inject(Duration.parse(\"-PT30S\"))",
-                "python": "g.inject(timedelta(seconds=-30))"
-            }
-        ]
-    },
-    {
-        "scenario": "g_injectXDurationXPT0_5SXX",
-        "traversals": [
-            {
-                "original": "g.inject(Duration(\"PT0.5S\"))",
-                "language": "g.inject(Duration(\"PT0.5S\"))",
-                "canonical": "g.inject(Duration(\"PT0.5S\"))",
-                "anonymized": "g.inject(duration0)",
-                "dotnet": 
"g.Inject<object>(XmlConvert.ToTimeSpan(\"PT0.5S\"))",
+                "dotnet": "g.Inject<object>(TimeSpan.FromTicks(5000000L))",
                 "go": "g.Inject(time.Duration(500000000))",
-                "groovy": "g.inject(Duration.parse(\"PT0.5S\"))",
-                "java": "g.inject(Duration.parse(\"PT0.5S\"))",
+                "groovy": "g.inject(Duration.ofSeconds(0, 500000000))",
+                "java": "g.inject(Duration.ofSeconds(0, 500000000))",
                 "python": "g.inject(timedelta(seconds=0,microseconds=500000))"
             }
         ]
     },
     {
-        "scenario": "g_injectXDurationXP1DT12HXX",
+        "scenario": "g_injectXDurationX30_0XX",
         "traversals": [
             {
-                "original": "g.inject(Duration(\"P1DT12H\"))",
-                "language": "g.inject(Duration(\"P1DT12H\"))",
-                "canonical": "g.inject(Duration(\"P1DT12H\"))",
+                "original": "g.inject(Duration(30, 0))",
+                "language": "g.inject(Duration(30,0))",
+                "canonical": "g.inject(Duration(30,0))",
                 "anonymized": "g.inject(duration0)",
-                "dotnet": "g.Inject<object>(XmlConvert.ToTimeSpan(\"PT36H\"))",
-                "go": "g.Inject(time.Duration(129600000000000))",
-                "groovy": "g.inject(Duration.parse(\"P1DT12H\"))",
-                "java": "g.inject(Duration.parse(\"P1DT12H\"))",
-                "python": "g.inject(timedelta(seconds=129600))"
+                "dotnet": "g.Inject<object>(TimeSpan.FromTicks(300000000L))",
+                "go": "g.Inject(time.Duration(30000000000))",
+                "groovy": "g.inject(Duration.ofSeconds(30, 0))",
+                "java": "g.inject(Duration.ofSeconds(30, 0))",
+                "python": "g.inject(timedelta(seconds=30))"
             }
         ]
     },
     {
-        "scenario": "g_injectXDurationXP2DXX",
+        "scenario": "g_injectXDurationX30_0_falseXX",
         "traversals": [
             {
-                "original": "g.inject(Duration(\"P2D\"))",
-                "language": "g.inject(Duration(\"P2D\"))",
-                "canonical": "g.inject(Duration(\"P2D\"))",
+                "original": "g.inject(Duration(30, 0, false))",
+                "language": "g.inject(Duration(30,0,false))",
+                "canonical": "g.inject(Duration(30,0,false))",
                 "anonymized": "g.inject(duration0)",
-                "dotnet": "g.Inject<object>(XmlConvert.ToTimeSpan(\"PT48H\"))",
-                "go": "g.Inject(time.Duration(172800000000000))",
-                "groovy": "g.inject(Duration.parse(\"P2D\"))",
-                "java": "g.inject(Duration.parse(\"P2D\"))",
-                "python": "g.inject(timedelta(seconds=172800))"
-            }
-        ]
-    },
-    {
-        "scenario": "g_injectXDurationXPT1H30M15SXX",
-        "traversals": [
-            {
-                "original": "g.inject(Duration(\"PT1H30M15S\"))",
-                "language": "g.inject(Duration(\"PT1H30M15S\"))",
-                "canonical": "g.inject(Duration(\"PT1H30M15S\"))",
-                "anonymized": "g.inject(duration0)",
-                "dotnet": 
"g.Inject<object>(XmlConvert.ToTimeSpan(\"PT1H30M15S\"))",
-                "go": "g.Inject(time.Duration(5415000000000))",
-                "groovy": "g.inject(Duration.parse(\"PT1H30M15S\"))",
-                "java": "g.inject(Duration.parse(\"PT1H30M15S\"))",
-                "python": "g.inject(timedelta(seconds=5415))"
+                "dotnet": 
"g.Inject<object>(TimeSpan.FromTicks(300000000L).Negate())",
+                "go": "g.Inject(time.Duration(-30000000000))",
+                "groovy": "g.inject(Duration.ofSeconds(30, 0).negated())",
+                "java": "g.inject(Duration.ofSeconds(30, 0).negated())",
+                "python": "g.inject(timedelta(seconds=-30))"
             }
         ]
     },
     {
-        "scenario": "g_injectXDurationXPTneg0_5SXX",
+        "scenario": "g_injectXDurationX1_500000000_falseXX",
         "traversals": [
             {
-                "original": "g.inject(Duration(\"PT-0.5S\"))",
-                "language": "g.inject(Duration(\"PT-0.5S\"))",
-                "canonical": "g.inject(Duration(\"PT-0.5S\"))",
+                "original": "g.inject(Duration(1, 500000000, false))",
+                "language": "g.inject(Duration(1,500000000,false))",
+                "canonical": "g.inject(Duration(1,500000000,false))",
                 "anonymized": "g.inject(duration0)",
-                "dotnet": 
"g.Inject<object>(XmlConvert.ToTimeSpan(\"-PT0.5S\"))",
-                "go": "g.Inject(time.Duration(-500000000))",
-                "groovy": "g.inject(Duration.parse(\"PT-0.5S\"))",
-                "java": "g.inject(Duration.parse(\"PT-0.5S\"))",
-                "python": "g.inject(timedelta(seconds=-1,microseconds=500000))"
+                "dotnet": 
"g.Inject<object>(TimeSpan.FromTicks(15000000L).Negate())",
+                "go": "g.Inject(time.Duration(-1500000000))",
+                "groovy": "g.inject(Duration.ofSeconds(1, 
500000000).negated())",
+                "java": "g.inject(Duration.ofSeconds(1, 500000000).negated())",
+                "python": 
"g.inject(timedelta(seconds=-1,microseconds=-500000))"
             }
         ]
     },
@@ -4041,14 +3993,14 @@
         "scenario": "g_valuesXlengthX_isXtypeOfXGType_DURATIONXX",
         "traversals": [
             {
-                "original": "g.addV(\"data\").property(\"length\", 
Duration(\"PT2H30M\"))",
-                "language": "g.addV(\"data\").property(\"length\", 
Duration(\"PT2H30M\"))",
-                "canonical": "g.addV(\"data\").property(\"length\", 
Duration(\"PT2H30M\"))",
+                "original": "g.addV(\"data\").property(\"length\", 
Duration(9000, 0))",
+                "language": "g.addV(\"data\").property(\"length\", 
Duration(9000,0))",
+                "canonical": "g.addV(\"data\").property(\"length\", 
Duration(9000,0))",
                 "anonymized": "g.addV(string0).property(string1, duration0)",
-                "dotnet": "g.AddV((string) \"data\").Property(\"length\", 
XmlConvert.ToTimeSpan(\"PT2H30M\"))",
+                "dotnet": "g.AddV((string) \"data\").Property(\"length\", 
TimeSpan.FromTicks(90000000000L))",
                 "go": "g.AddV(\"data\").Property(\"length\", 
time.Duration(9000000000000))",
-                "groovy": "g.addV(\"data\").property(\"length\", 
Duration.parse(\"PT2H30M\"))",
-                "java": "g.addV(\"data\").property(\"length\", 
Duration.parse(\"PT2H30M\"))",
+                "groovy": "g.addV(\"data\").property(\"length\", 
Duration.ofSeconds(9000, 0))",
+                "java": "g.addV(\"data\").property(\"length\", 
Duration.ofSeconds(9000, 0))",
                 "python": "g.add_v('data').property('length', 
timedelta(seconds=9000))"
             },
             {
@@ -4066,17 +4018,17 @@
         ]
     },
     {
-        "scenario": "g_injectXDurationXPT2H30MXX_isXgtXDurationXPT1HXXX",
+        "scenario": "g_injectXDurationX9000_0XX_isXgtXDurationX3600_0XXX",
         "traversals": [
             {
-                "original": 
"g.inject(Duration(\"PT2H30M\")).is(P.gt(Duration(\"PT1H\")))",
-                "language": 
"g.inject(Duration(\"PT2H30M\")).is(P.gt(Duration(\"PT1H\")))",
-                "canonical": 
"g.inject(Duration(\"PT2H30M\")).is(P.gt(Duration(\"PT1H\")))",
+                "original": "g.inject(Duration(9000, 
0)).is(P.gt(Duration(3600, 0)))",
+                "language": 
"g.inject(Duration(9000,0)).is(P.gt(Duration(3600,0)))",
+                "canonical": 
"g.inject(Duration(9000,0)).is(P.gt(Duration(3600,0)))",
                 "anonymized": "g.inject(duration0).is(P.gt(duration1))",
-                "dotnet": 
"g.Inject<object>(XmlConvert.ToTimeSpan(\"PT2H30M\")).Is(P.Gt(XmlConvert.ToTimeSpan(\"PT1H\")))",
+                "dotnet": 
"g.Inject<object>(TimeSpan.FromTicks(90000000000L)).Is(P.Gt(TimeSpan.FromTicks(36000000000L)))",
                 "go": 
"g.Inject(time.Duration(9000000000000)).Is(gremlingo.P.Gt(time.Duration(3600000000000)))",
-                "groovy": 
"g.inject(Duration.parse(\"PT2H30M\")).is(P.gt(Duration.parse(\"PT1H\")))",
-                "java": 
"g.inject(Duration.parse(\"PT2H30M\")).is(P.gt(Duration.parse(\"PT1H\")))",
+                "groovy": "g.inject(Duration.ofSeconds(9000, 
0)).is(P.gt(Duration.ofSeconds(3600, 0)))",
+                "java": "g.inject(Duration.ofSeconds(9000, 
0)).is(P.gt(Duration.ofSeconds(3600, 0)))",
                 "python": 
"g.inject(timedelta(seconds=9000)).is_(P.gt(timedelta(seconds=3600)))"
             }
         ]
diff --git 
a/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/test/features/data/Duration.feature
 
b/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/test/features/data/Duration.feature
index c9d0a73686..5f2da18e77 100644
--- 
a/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/test/features/data/Duration.feature
+++ 
b/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/test/features/data/Duration.feature
@@ -19,118 +19,82 @@
 Feature: Data - DURATION
 
   @GraphComputerVerificationInjectionNotSupported
-  Scenario: g_injectXDurationXPT2H30MXX
+  Scenario: g_injectXDurationX9000_0XX
     Given the empty graph
     And the traversal of
       """
-      g.inject(Duration("PT2H30M"))
+      g.inject(Duration(9000, 0))
       """
     When iterated to list
     Then the result should be unordered
       | result |
-      | dur[PT2H30M] |
+      | dur[9000,0] |
 
   @GraphComputerVerificationInjectionNotSupported
-  Scenario: g_injectXDurationXPT0SXX
+  Scenario: g_injectXDurationX0_0XX
     Given the empty graph
     And the traversal of
       """
-      g.inject(Duration("PT0S"))
+      g.inject(Duration(0, 0))
       """
     When iterated to list
     Then the result should be unordered
       | result |
-      | dur[PT0S] |
+      | dur[0,0] |
 
   @GraphComputerVerificationInjectionNotSupported
-  Scenario: g_injectXDurationXPTneg30SXX
+  Scenario: g_injectXDurationX0_500000000XX
     Given the empty graph
     And the traversal of
       """
-      g.inject(Duration("PT-30S"))
+      g.inject(Duration(0, 500000000))
       """
     When iterated to list
     Then the result should be unordered
       | result |
-      | dur[PT-30S] |
+      | dur[0,500000000] |
 
   @GraphComputerVerificationInjectionNotSupported
-  Scenario: g_injectXDurationXnegPT30SXX
+  Scenario: g_injectXDurationX30_0XX
     Given the empty graph
     And the traversal of
       """
-      g.inject(Duration("-PT30S"))
+      g.inject(Duration(30, 0))
       """
     When iterated to list
     Then the result should be unordered
       | result |
-      | dur[PT-30S] |
+      | dur[30,0] |
 
   @GraphComputerVerificationInjectionNotSupported
-  Scenario: g_injectXDurationXPT0_5SXX
+  Scenario: g_injectXDurationX30_0_falseXX
     Given the empty graph
     And the traversal of
       """
-      g.inject(Duration("PT0.5S"))
+      g.inject(Duration(30, 0, false))
       """
     When iterated to list
     Then the result should be unordered
       | result |
-      | dur[PT0.5S] |
+      | dur[30,0,false] |
 
   @GraphComputerVerificationInjectionNotSupported
-  Scenario: g_injectXDurationXP1DT12HXX
+  Scenario: g_injectXDurationX1_500000000_falseXX
     Given the empty graph
     And the traversal of
       """
-      g.inject(Duration("P1DT12H"))
+      g.inject(Duration(1, 500000000, false))
       """
     When iterated to list
     Then the result should be unordered
       | result |
-      | dur[PT36H] |
-
-  @GraphComputerVerificationInjectionNotSupported
-  Scenario: g_injectXDurationXP2DXX
-    Given the empty graph
-    And the traversal of
-      """
-      g.inject(Duration("P2D"))
-      """
-    When iterated to list
-    Then the result should be unordered
-      | result |
-      | dur[PT48H] |
-
-  @GraphComputerVerificationInjectionNotSupported
-  Scenario: g_injectXDurationXPT1H30M15SXX
-    Given the empty graph
-    And the traversal of
-      """
-      g.inject(Duration("PT1H30M15S"))
-      """
-    When iterated to list
-    Then the result should be unordered
-      | result |
-      | dur[PT1H30M15S] |
-
-  @GraphComputerVerificationInjectionNotSupported
-  Scenario: g_injectXDurationXPTneg0_5SXX
-    Given the empty graph
-    And the traversal of
-      """
-      g.inject(Duration("PT-0.5S"))
-      """
-    When iterated to list
-    Then the result should be unordered
-      | result |
-      | dur[PT-0.5S] |
+      | dur[1,500000000,false] |
 
   Scenario: g_valuesXlengthX_isXtypeOfXGType_DURATIONXX
     Given the empty graph
     And the graph initializer of
       """
-      g.addV("data").property("length", Duration("PT2H30M"))
+      g.addV("data").property("length", Duration(9000, 0))
       """
     And the traversal of
       """
@@ -139,16 +103,16 @@ Feature: Data - DURATION
     When iterated to list
     Then the result should be unordered
       | result |
-      | dur[PT2H30M] |
+      | dur[9000,0] |
 
   @GraphComputerVerificationInjectionNotSupported
-  Scenario: g_injectXDurationXPT2H30MXX_isXgtXDurationXPT1HXXX
+  Scenario: g_injectXDurationX9000_0XX_isXgtXDurationX3600_0XXX
     Given the empty graph
     And the traversal of
       """
-      g.inject(Duration("PT2H30M")).is(P.gt(Duration("PT1H")))
+      g.inject(Duration(9000, 0)).is(P.gt(Duration(3600, 0)))
       """
     When iterated to list
     Then the result should be unordered
       | result |
-      | dur[PT2H30M] |
+      | dur[9000,0] |


Reply via email to