diff --git a/main/src/com/google/refine/expr/functions/date/Inc.java b/main/src/com/google/refine/expr/functions/date/Inc.java index 9ad1a1719..ff521d620 100644 --- a/main/src/com/google/refine/expr/functions/date/Inc.java +++ b/main/src/com/google/refine/expr/functions/date/Inc.java @@ -78,6 +78,10 @@ public class Inc implements Function { return ChronoUnit.WEEKS; } else if ("seconds".equals(unit) || "sec".equals(unit) || "s".equals(unit)) { return ChronoUnit.SECONDS; + } else if ("milliseconds".equals(unit) || "ms".equals(unit) || "S".equals(unit)) { + return ChronoUnit.MILLIS; + } else if ("nanos".equals(unit) || "nano".equals(unit) || "n".equals(unit)) { + return ChronoUnit.NANOS; } else { throw new RuntimeException("Unit '" + unit + "' not recognized."); } diff --git a/main/src/com/google/refine/expr/functions/strings/Diff.java b/main/src/com/google/refine/expr/functions/strings/Diff.java index 855b5a352..155b0bfea 100644 --- a/main/src/com/google/refine/expr/functions/strings/Diff.java +++ b/main/src/com/google/refine/expr/functions/strings/Diff.java @@ -60,7 +60,17 @@ public class Diff implements Function { OffsetDateTime c1 = (OffsetDateTime)o1; OffsetDateTime c2 = (OffsetDateTime)o2; - long delta = (c1.toInstant().toEpochMilli() - c2.toInstant().toEpochMilli()) / 1000; + long delta = getNano(c1) - getNano(c2); + if ("nanos".equals(unit)) { + return delta; + } + + delta /= 1000; + if ("milliseconds".equals(unit)) { + return delta; + } + + delta /= 1000000; if ("seconds".equals(unit)) { return delta; } @@ -101,4 +111,8 @@ public class Diff implements Function { writer.key("returns"); writer.value("string for strings, number for dates"); writer.endObject(); } + + private long getNano(OffsetDateTime odt) { + return odt.toEpochSecond() * 1000000000l + odt.toInstant().getNano(); + } } diff --git a/main/tests/server/src/com/google/refine/tests/expr/functions/date/IncTests.java b/main/tests/server/src/com/google/refine/tests/expr/functions/date/IncTests.java index c7b6608e9..e1905b5c0 100644 --- a/main/tests/server/src/com/google/refine/tests/expr/functions/date/IncTests.java +++ b/main/tests/server/src/com/google/refine/tests/expr/functions/date/IncTests.java @@ -101,6 +101,18 @@ public class IncTests extends RefineTest { Assert.assertEquals(invoke("inc", source, 2, "sec"), source.plus(2, ChronoUnit.SECONDS)); Assert.assertEquals(invoke("inc", source, 2, "s"), source.plus(2, ChronoUnit.SECONDS)); + // add milliseconds + Assert.assertTrue(invoke("inc", source, 2, "milliseconds") instanceof OffsetDateTime); + Assert.assertEquals(invoke("inc", source, 2, "milliseconds"), source.plus(2, ChronoUnit.MILLIS)); + Assert.assertEquals(invoke("inc", source, 2, "ms"), source.plus(2, ChronoUnit.MILLIS)); + Assert.assertEquals(invoke("inc", source, 2, "S"), source.plus(2, ChronoUnit.MILLIS)); + + // add nanos + Assert.assertTrue(invoke("inc", source, 2, "nanos") instanceof OffsetDateTime); + Assert.assertEquals(invoke("inc", source, 2, "nanos"), source.plus(2, ChronoUnit.NANOS)); + Assert.assertEquals(invoke("inc", source, 2, "nano"), source.plus(2, ChronoUnit.NANOS)); + Assert.assertEquals(invoke("inc", source, 2, "n"), source.plus(2, ChronoUnit.NANOS)); + // exception Assert.assertTrue(invoke("inc", source, 99) instanceof EvalError); Assert.assertTrue(invoke("inc", source.toInstant().toEpochMilli(), 99, "h") instanceof EvalError); diff --git a/main/tests/server/src/com/google/refine/tests/expr/functions/strings/DiffTests.java b/main/tests/server/src/com/google/refine/tests/expr/functions/strings/DiffTests.java index 7f98278fa..92f44c6c7 100644 --- a/main/tests/server/src/com/google/refine/tests/expr/functions/strings/DiffTests.java +++ b/main/tests/server/src/com/google/refine/tests/expr/functions/strings/DiffTests.java @@ -28,8 +28,8 @@ public class DiffTests extends RefineTest { @BeforeTest public void init() { logger = LoggerFactory.getLogger(this.getClass()); - odt1 = OffsetDateTime.parse("2011-09-01T10:15:30+01:00", DateTimeFormatter.ISO_OFFSET_DATE_TIME); - odt2 = OffsetDateTime.parse("2011-12-02T10:16:30+01:00", DateTimeFormatter.ISO_OFFSET_DATE_TIME); + odt1 = OffsetDateTime.parse("2011-09-01T10:15:30.123456+01:00", DateTimeFormatter.ISO_OFFSET_DATE_TIME); + odt2 = OffsetDateTime.parse("2011-12-02T10:16:30.123467+01:00", DateTimeFormatter.ISO_OFFSET_DATE_TIME); } @BeforeMethod @@ -77,5 +77,7 @@ public class DiffTests extends RefineTest { Assert.assertEquals(invoke("diff",odt2,odt1,"months"),Long.valueOf(3)); Assert.assertEquals(invoke("diff",odt2,odt1,"hours"),Long.valueOf(2208)); Assert.assertEquals(invoke("diff",odt2,odt1,"seconds"),Long.valueOf(7948860)); + Assert.assertEquals(invoke("diff",odt2,odt1,"milliseconds"),Long.valueOf(7948860000011l)); + Assert.assertEquals(invoke("diff",odt2,odt1,"nanos"),Long.valueOf(7948860000011000l)); } }