You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@isis.apache.org by ah...@apache.org on 2021/11/23 13:40:29 UTC

[isis] branch master updated: ISIS-2877: wire-up new OrderRelation for all temporal types

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

ahuber pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/isis.git


The following commit(s) were added to refs/heads/master by this push:
     new 17bb601  ISIS-2877: wire-up new OrderRelation for all temporal types
17bb601 is described below

commit 17bb601bf34ac3d48b751622d96bce299c87adfc
Author: Andi Huber <ah...@apache.org>
AuthorDate: Tue Nov 23 14:40:22 2021 +0100

    ISIS-2877: wire-up new OrderRelation for all temporal types
---
 .../isis/applib/value/semantics/OrderRelation.java | 24 ++++++++++++++--
 .../value/semantics/TemporalValueSemantics.java    |  2 ++
 .../value/semantics/ValueSemanticsAbstract.java    |  1 +
 .../facets/object/value/ValueFacetAbstract.java    |  2 +-
 .../temporal/LocalDateTimeValueSemantics.java      | 12 +++++++-
 .../temporal/LocalDateValueSemantics.java          | 12 +++++++-
 .../temporal/LocalTimeValueSemantics.java          |  8 ++++++
 .../temporal/OffsetDateTimeValueSemantics.java     |  8 ++++++
 .../temporal/OffsetTimeValueSemantics.java         |  8 ++++++
 .../temporal/TemporalValueSemanticsProvider.java   | 29 ++++++++++++++++++++
 .../temporal/ZonedDateTimeValueSemantics.java      |  8 ++++++
 .../temporal/legacy/JavaSqlDateValueSemantics.java |  5 ++--
 .../legacy/JavaSqlTimeStampValueSemantics.java     |  4 +--
 .../temporal/legacy/JavaSqlTimeValueSemantics.java |  4 +--
 .../legacy/JavaUtilDateValueSemantics.java         |  4 +--
 .../valuetypes/TemporalSemanticsAdapter.java       | 32 ++++++++++++++++++++++
 .../valuetypes/ValueSemanticsAdapter.java          | 29 +++++++++++++++++++-
 .../testdomain/value/ValueSemanticsTester.java     | 16 +++++++----
 .../valuesemantics/JodaDateTimeValueSemantics.java |  4 +--
 .../JodaLocalDateTimeValueSemantics.java           |  4 +--
 .../JodaLocalDateValueSemantics.java               |  4 +--
 .../JodaLocalTimeValueSemantics.java               |  4 +--
 22 files changed, 196 insertions(+), 28 deletions(-)

diff --git a/api/applib/src/main/java/org/apache/isis/applib/value/semantics/OrderRelation.java b/api/applib/src/main/java/org/apache/isis/applib/value/semantics/OrderRelation.java
index 0a61084..3a9f22d 100644
--- a/api/applib/src/main/java/org/apache/isis/applib/value/semantics/OrderRelation.java
+++ b/api/applib/src/main/java/org/apache/isis/applib/value/semantics/OrderRelation.java
@@ -1,3 +1,21 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
 package org.apache.isis.applib.value.semantics;
 
 /**
@@ -25,12 +43,12 @@ package org.apache.isis.applib.value.semantics;
 public interface OrderRelation<T, D> {
 
     /**
-     * Default epsilon (measure of accuracy), if not specified.
+     * Default epsilon (measure of accuracy).
      */
     D epsilon();
 
     /**
-     * @param epsilon - measure of accuracy, has different meaning, depending on context
+     * @param epsilon - measure of accuracy
      */
     int compare(T a, T b, D epsilon);
 
@@ -39,7 +57,7 @@ public interface OrderRelation<T, D> {
     }
 
     /**
-     * @param epsilon - measure of accuracy, has different meaning, depending on context
+     * @param epsilon - measure of accuracy
      */
     boolean equals(T a, T b, D epsilon);
 
diff --git a/api/applib/src/main/java/org/apache/isis/applib/value/semantics/TemporalValueSemantics.java b/api/applib/src/main/java/org/apache/isis/applib/value/semantics/TemporalValueSemantics.java
index caf5e45..33fb86d 100644
--- a/api/applib/src/main/java/org/apache/isis/applib/value/semantics/TemporalValueSemantics.java
+++ b/api/applib/src/main/java/org/apache/isis/applib/value/semantics/TemporalValueSemantics.java
@@ -18,6 +18,7 @@
  */
 package org.apache.isis.applib.value.semantics;
 
+import java.time.Duration;
 import java.time.temporal.Temporal;
 
 /**
@@ -29,6 +30,7 @@ import java.time.temporal.Temporal;
  */
 public interface TemporalValueSemantics<T extends Temporal>
 extends
+    OrderRelation<T, Duration>,
     EncoderDecoder<T>,
     Parser<T>,
     Renderer<T> {
diff --git a/api/applib/src/main/java/org/apache/isis/applib/value/semantics/ValueSemanticsAbstract.java b/api/applib/src/main/java/org/apache/isis/applib/value/semantics/ValueSemanticsAbstract.java
index eed725c..89f36ec 100644
--- a/api/applib/src/main/java/org/apache/isis/applib/value/semantics/ValueSemanticsAbstract.java
+++ b/api/applib/src/main/java/org/apache/isis/applib/value/semantics/ValueSemanticsAbstract.java
@@ -103,6 +103,7 @@ implements
      * this is typically overruled later by implementations of
      * {@link #configureDecimalFormat(org.apache.isis.applib.adapters.ValueSemanticsProvider.Context, DecimalFormat) configureDecimalFormat}
      */
+    @SuppressWarnings("javadoc")
     protected DecimalFormat getNumberFormat(final @Nullable ValueSemanticsProvider.Context context) {
         val format = (DecimalFormat)NumberFormat.getNumberInstance(getLocale(context));
         // prime w/ 16 (64 bit IEEE 754 double has 15 decimal digits of precision)
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/value/ValueFacetAbstract.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/value/ValueFacetAbstract.java
index c3a1c1d..f1b7a7c 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/value/ValueFacetAbstract.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/value/ValueFacetAbstract.java
@@ -107,7 +107,7 @@ implements ValueFacet<T> {
                 iaProvider.currentInteractionContext().orElse(null));
     }
 
-    // -- ORDER RELATIONN
+    // -- ORDER RELATION
 
     @Override
     public Optional<OrderRelation<T, ?>> selectDefaultOrderRelation() {
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/temporal/LocalDateTimeValueSemantics.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/temporal/LocalDateTimeValueSemantics.java
index d1c0c13..f8f1d7e 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/temporal/LocalDateTimeValueSemantics.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/temporal/LocalDateTimeValueSemantics.java
@@ -18,19 +18,22 @@
  */
 package org.apache.isis.core.metamodel.valuesemantics.temporal;
 
+import java.time.Duration;
 import java.time.LocalDateTime;
 
 import javax.inject.Named;
 
 import org.springframework.stereotype.Component;
 
+import org.apache.isis.applib.value.semantics.OrderRelation;
 import org.apache.isis.schema.common.v2.ValueType;
 
 @Component
 @Named("isis.val.LocalDateTimeValueSemantics")
 //@Log4j2
 public class LocalDateTimeValueSemantics
-extends TemporalValueSemanticsProvider<LocalDateTime> {
+extends TemporalValueSemanticsProvider<LocalDateTime>
+implements OrderRelation<LocalDateTime, Duration> {
 
     public static final int MAX_LENGTH = 36;
     public static final int TYPICAL_LENGTH = 22;
@@ -52,4 +55,11 @@ extends TemporalValueSemanticsProvider<LocalDateTime> {
                 TemporalAdjust::adjustLocalDateTime);
     }
 
+    // -- ORDER RELATION
+
+    @Override
+    public Duration epsilon() {
+        return ALMOST_A_SECOND;
+    }
+
 }
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/temporal/LocalDateValueSemantics.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/temporal/LocalDateValueSemantics.java
index 88ca29e..f9f92ea 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/temporal/LocalDateValueSemantics.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/temporal/LocalDateValueSemantics.java
@@ -18,19 +18,22 @@
  */
 package org.apache.isis.core.metamodel.valuesemantics.temporal;
 
+import java.time.Duration;
 import java.time.LocalDate;
 
 import javax.inject.Named;
 
 import org.springframework.stereotype.Component;
 
+import org.apache.isis.applib.value.semantics.OrderRelation;
 import org.apache.isis.schema.common.v2.ValueType;
 
 @Component
 @Named("isis.val.LocalDateValueSemantics")
 //@Log4j2
 public class LocalDateValueSemantics
-extends TemporalValueSemanticsProvider<LocalDate> {
+extends TemporalValueSemanticsProvider<LocalDate>
+implements OrderRelation<LocalDate, Duration> {
 
     public static final int MAX_LENGTH = 12;
     public static final int TYPICAL_LENGTH = MAX_LENGTH;
@@ -52,4 +55,11 @@ extends TemporalValueSemanticsProvider<LocalDate> {
                 TemporalAdjust::adjustLocalDate);
     }
 
+    // -- ORDER RELATION
+
+    @Override
+    public Duration epsilon() {
+        return Duration.ZERO; // not used for dates, as these are integer based
+    }
+
 }
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/temporal/LocalTimeValueSemantics.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/temporal/LocalTimeValueSemantics.java
index 70cd643..24f236b 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/temporal/LocalTimeValueSemantics.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/temporal/LocalTimeValueSemantics.java
@@ -18,6 +18,7 @@
  */
 package org.apache.isis.core.metamodel.valuesemantics.temporal;
 
+import java.time.Duration;
 import java.time.LocalTime;
 
 import javax.inject.Named;
@@ -52,4 +53,11 @@ extends TemporalValueSemanticsProvider<LocalTime> {
                 TemporalAdjust::adjustLocalTime);
     }
 
+    // -- ORDER RELATION
+
+    @Override
+    public Duration epsilon() {
+        return ALMOST_A_SECOND;
+    }
+
 }
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/temporal/OffsetDateTimeValueSemantics.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/temporal/OffsetDateTimeValueSemantics.java
index 75a0a45..e64168b 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/temporal/OffsetDateTimeValueSemantics.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/temporal/OffsetDateTimeValueSemantics.java
@@ -18,6 +18,7 @@
  */
 package org.apache.isis.core.metamodel.valuesemantics.temporal;
 
+import java.time.Duration;
 import java.time.OffsetDateTime;
 
 import javax.inject.Named;
@@ -52,4 +53,11 @@ extends TemporalValueSemanticsProvider<OffsetDateTime> {
                 TemporalAdjust::adjustOffsetDateTime);
     }
 
+    // -- ORDER RELATION
+
+    @Override
+    public Duration epsilon() {
+        return ALMOST_A_SECOND;
+    }
+
 }
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/temporal/OffsetTimeValueSemantics.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/temporal/OffsetTimeValueSemantics.java
index 97b265f..8ae0eb6 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/temporal/OffsetTimeValueSemantics.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/temporal/OffsetTimeValueSemantics.java
@@ -18,6 +18,7 @@
  */
 package org.apache.isis.core.metamodel.valuesemantics.temporal;
 
+import java.time.Duration;
 import java.time.OffsetTime;
 
 import javax.inject.Named;
@@ -52,5 +53,12 @@ extends TemporalValueSemanticsProvider<OffsetTime> {
                 TemporalAdjust::adjustOffsetTime);
     }
 
+    // -- ORDER RELATION
+
+    @Override
+    public Duration epsilon() {
+        return ALMOST_A_SECOND;
+    }
+
 
 }
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/temporal/TemporalValueSemanticsProvider.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/temporal/TemporalValueSemanticsProvider.java
index 0954370..e7d2a83 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/temporal/TemporalValueSemanticsProvider.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/temporal/TemporalValueSemanticsProvider.java
@@ -18,8 +18,10 @@
  */
 package org.apache.isis.core.metamodel.valuesemantics.temporal;
 
+import java.time.Duration;
 import java.time.format.DateTimeFormatter;
 import java.time.format.FormatStyle;
+import java.time.temporal.ChronoUnit;
 import java.time.temporal.Temporal;
 import java.time.temporal.TemporalQuery;
 import java.util.function.BiFunction;
@@ -32,6 +34,7 @@ import org.apache.isis.applib.value.semantics.ValueSemanticsProvider;
 import org.apache.isis.commons.internal.base._Strings;
 
 import lombok.Getter;
+import lombok.NonNull;
 import lombok.val;
 import lombok.experimental.Accessors;
 
@@ -78,6 +81,32 @@ implements TemporalValueSemantics<T> {
         this.adjuster = adjuster;
     }
 
+    // -- ORDER RELATION
+
+    protected final static Duration ALMOST_A_SECOND = Duration.ofNanos(999_999_999);
+    protected final static Duration ALMOST_A_MILLI_SECOND = Duration.ofNanos(999_999);
+
+    @Override
+    public final int compare(final T a, final T b, final @NonNull Duration epsilon) {
+
+        val delta = (!a.isSupported(ChronoUnit.SECONDS))
+                ? Duration.ofDays(a.until(b, ChronoUnit.DAYS))
+                : Duration.between(a, b);
+
+        if(epsilon.minus(delta.abs()).isNegative()) {
+            // negative delta means a > b => should return +1
+            return delta.isNegative()
+                    ? 1
+                    : -1;
+        }
+        return 0;
+    }
+
+    @Override
+    public final boolean equals(final T a, final T b, final @NonNull Duration epsilon) {
+        return compare(a, b, epsilon) == 0;
+    }
+
     // -- ENCODER/DECODER
 
     @Override
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/temporal/ZonedDateTimeValueSemantics.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/temporal/ZonedDateTimeValueSemantics.java
index 9301b0b..33db215 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/temporal/ZonedDateTimeValueSemantics.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/temporal/ZonedDateTimeValueSemantics.java
@@ -18,6 +18,7 @@
  */
 package org.apache.isis.core.metamodel.valuesemantics.temporal;
 
+import java.time.Duration;
 import java.time.ZonedDateTime;
 
 import javax.inject.Named;
@@ -52,4 +53,11 @@ extends TemporalValueSemanticsProvider<ZonedDateTime> {
                 TemporalAdjust::adjustZonedDateTime);
     }
 
+    // -- ORDER RELATION
+
+    @Override
+    public Duration epsilon() {
+        return ALMOST_A_SECOND;
+    }
+
 }
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/temporal/legacy/JavaSqlDateValueSemantics.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/temporal/legacy/JavaSqlDateValueSemantics.java
index c416a96..966a97e 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/temporal/legacy/JavaSqlDateValueSemantics.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/temporal/legacy/JavaSqlDateValueSemantics.java
@@ -28,7 +28,7 @@ import org.springframework.stereotype.Component;
 
 import org.apache.isis.applib.value.semantics.ValueSemanticsAbstract;
 import org.apache.isis.core.metamodel.valuesemantics.temporal.LocalDateValueSemantics;
-import org.apache.isis.core.metamodel.valuetypes.ValueSemanticsAdapter;
+import org.apache.isis.core.metamodel.valuetypes.TemporalSemanticsAdapter;
 import org.apache.isis.schema.common.v2.ValueType;
 
 /**
@@ -40,7 +40,7 @@ import org.apache.isis.schema.common.v2.ValueType;
 @Component
 @Named("isis.val.JavaSqlDateValueSemantics")
 public class JavaSqlDateValueSemantics
-extends ValueSemanticsAdapter<Date, LocalDate>  {
+extends TemporalSemanticsAdapter<Date, LocalDate> {
 
     @Inject LocalDateValueSemantics localDateValueSemantics;
 
@@ -69,4 +69,5 @@ extends ValueSemanticsAdapter<Date, LocalDate>  {
         return value.toLocalDate();
     }
 
+
 }
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/temporal/legacy/JavaSqlTimeStampValueSemantics.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/temporal/legacy/JavaSqlTimeStampValueSemantics.java
index 1fcaec4..959a823 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/temporal/legacy/JavaSqlTimeStampValueSemantics.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/temporal/legacy/JavaSqlTimeStampValueSemantics.java
@@ -28,13 +28,13 @@ import org.springframework.stereotype.Component;
 
 import org.apache.isis.applib.value.semantics.ValueSemanticsAbstract;
 import org.apache.isis.core.metamodel.valuesemantics.temporal.LocalDateTimeValueSemantics;
-import org.apache.isis.core.metamodel.valuetypes.ValueSemanticsAdapter;
+import org.apache.isis.core.metamodel.valuetypes.TemporalSemanticsAdapter;
 import org.apache.isis.schema.common.v2.ValueType;
 
 @Component
 @Named("isis.val.JavaSqlTimeStampValueSemantics")
 public class JavaSqlTimeStampValueSemantics
-extends ValueSemanticsAdapter<Timestamp, LocalDateTime>  {
+extends TemporalSemanticsAdapter<Timestamp, LocalDateTime> {
 
     @Inject LocalDateTimeValueSemantics localDateTimeValueSemantics;
 
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/temporal/legacy/JavaSqlTimeValueSemantics.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/temporal/legacy/JavaSqlTimeValueSemantics.java
index 843d404..8200432 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/temporal/legacy/JavaSqlTimeValueSemantics.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/temporal/legacy/JavaSqlTimeValueSemantics.java
@@ -28,7 +28,7 @@ import org.springframework.stereotype.Component;
 
 import org.apache.isis.applib.value.semantics.ValueSemanticsAbstract;
 import org.apache.isis.core.metamodel.valuesemantics.temporal.LocalTimeValueSemantics;
-import org.apache.isis.core.metamodel.valuetypes.ValueSemanticsAdapter;
+import org.apache.isis.core.metamodel.valuetypes.TemporalSemanticsAdapter;
 import org.apache.isis.schema.common.v2.ValueType;
 
 /**
@@ -38,7 +38,7 @@ import org.apache.isis.schema.common.v2.ValueType;
 @Component
 @Named("isis.val.JavaSqlTimeValueSemantics")
 public class JavaSqlTimeValueSemantics
-extends ValueSemanticsAdapter<Time, LocalTime>  {
+extends TemporalSemanticsAdapter<Time, LocalTime>  {
 
     @Inject LocalTimeValueSemantics localTimeValueSemantics;
 
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/temporal/legacy/JavaUtilDateValueSemantics.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/temporal/legacy/JavaUtilDateValueSemantics.java
index e8eaca0..08fff1d 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/temporal/legacy/JavaUtilDateValueSemantics.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/temporal/legacy/JavaUtilDateValueSemantics.java
@@ -29,7 +29,7 @@ import org.springframework.stereotype.Component;
 
 import org.apache.isis.applib.value.semantics.ValueSemanticsAbstract;
 import org.apache.isis.core.metamodel.valuesemantics.temporal.LocalDateTimeValueSemantics;
-import org.apache.isis.core.metamodel.valuetypes.ValueSemanticsAdapter;
+import org.apache.isis.core.metamodel.valuetypes.TemporalSemanticsAdapter;
 import org.apache.isis.schema.common.v2.ValueType;
 
 /**
@@ -42,7 +42,7 @@ import org.apache.isis.schema.common.v2.ValueType;
 @Component
 @Named("isis.val.JavaUtilDateValueSemantics")
 public class JavaUtilDateValueSemantics
-extends ValueSemanticsAdapter<Date, LocalDateTime>  {
+extends TemporalSemanticsAdapter<Date, LocalDateTime>  {
 
     @Inject LocalDateTimeValueSemantics localDateTimeValueSemantics;
 
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuetypes/TemporalSemanticsAdapter.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuetypes/TemporalSemanticsAdapter.java
new file mode 100644
index 0000000..b028657
--- /dev/null
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuetypes/TemporalSemanticsAdapter.java
@@ -0,0 +1,32 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package org.apache.isis.core.metamodel.valuetypes;
+
+import java.time.Duration;
+import java.time.temporal.Temporal;
+
+public abstract class TemporalSemanticsAdapter<T, D extends Temporal>
+extends ValueSemanticsAdapter<T, D, Duration> {
+
+    // -- ORDER RELATION
+
+    protected final static Duration ALMOST_A_SECOND = Duration.ofNanos(999_999_999);
+    protected final static Duration ALMOST_A_MILLI_SECOND = Duration.ofNanos(999_999);
+
+}
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuetypes/ValueSemanticsAdapter.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuetypes/ValueSemanticsAdapter.java
index 51519fb..0ebf9fd 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuetypes/ValueSemanticsAdapter.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuetypes/ValueSemanticsAdapter.java
@@ -19,6 +19,7 @@
 package org.apache.isis.core.metamodel.valuetypes;
 
 import org.apache.isis.applib.value.semantics.EncoderDecoder;
+import org.apache.isis.applib.value.semantics.OrderRelation;
 import org.apache.isis.applib.value.semantics.Parser;
 import org.apache.isis.applib.value.semantics.Renderer;
 import org.apache.isis.applib.value.semantics.ValueSemanticsAbstract;
@@ -26,9 +27,10 @@ import org.apache.isis.applib.value.semantics.ValueSemanticsProvider;
 
 import lombok.val;
 
-public abstract class ValueSemanticsAdapter<T, D>
+public abstract class ValueSemanticsAdapter<T, D, E>
 extends ValueSemanticsAbstract<T>
 implements
+    OrderRelation<T, E>,
     EncoderDecoder<T>,
     Parser<T>,
     Renderer<T> {
@@ -38,6 +40,26 @@ implements
     public abstract T fromDelegateValue(D value);
     public abstract D toDelegateValue(T value);
 
+    // -- ORDER RELATION
+
+    @Override
+    public final E epsilon() {
+        return delegateOrderRelation().epsilon();
+    }
+
+    @Override
+    public final int compare(final T a, final T b, final E epsilon) {
+        return delegateOrderRelation()
+                .compare(toDelegateValue(a), toDelegateValue(b), epsilon);
+    }
+
+    @Override
+    public final boolean equals(final T a, final T b, final E epsilon) {
+        return delegateOrderRelation()
+                .equals(toDelegateValue(a), toDelegateValue(b), epsilon);
+    }
+
+
     // -- ENCODER DECODER
 
     @Override
@@ -93,6 +115,11 @@ implements
     // -- HELPER
 
     @SuppressWarnings({ "rawtypes", "unchecked" })
+    private OrderRelation<D, E> delegateOrderRelation() {
+        return ((OrderRelation)getDelegate());
+    }
+
+    @SuppressWarnings({ "rawtypes", "unchecked" })
     private Parser<D> delegateParser() {
         return ((Parser)getDelegate());
     }
diff --git a/regressiontests/stable-value/src/test/java/org/apache/isis/testdomain/value/ValueSemanticsTester.java b/regressiontests/stable-value/src/test/java/org/apache/isis/testdomain/value/ValueSemanticsTester.java
index 5cb7cf6..8e0bb46 100644
--- a/regressiontests/stable-value/src/test/java/org/apache/isis/testdomain/value/ValueSemanticsTester.java
+++ b/regressiontests/stable-value/src/test/java/org/apache/isis/testdomain/value/ValueSemanticsTester.java
@@ -25,6 +25,7 @@ import java.util.function.Function;
 import javax.inject.Inject;
 
 import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertTrue;
 
 import org.apache.isis.applib.annotation.Where;
 import org.apache.isis.applib.services.command.Command;
@@ -125,7 +126,10 @@ public class ValueSemanticsTester<T extends Serializable> {
 
     // -- UTILITY
 
-    public void assertValueEquals(final T a, final Object b, final String message) {
+    public void assertValueEquals(final T a, final Object _b, final String message) {
+
+        val b = _Casts.<T>uncheckedCast(_b);
+
         if(valueType.equals(java.util.Date.class)
                 || valueType.getPackageName().equals("java.sql")
                 || valueType.getPackageName().equals("java.time")
@@ -134,14 +138,16 @@ public class ValueSemanticsTester<T extends Serializable> {
 
             //TODO implement based on OrderRelation<T>
             //assertEquals(a, b, message);
-            return;
+            //return;
         }
 
         if(currentOrderRelation.isPresent()) {
-            currentOrderRelation.get().equals(a, (T)b);
+            assertTrue(currentOrderRelation.get().equals(a, b), ()->
+                String.format("%s ==> expected: %s but was: %s",
+                        message, ""+a, ""+b));
+        } else {
+            assertEquals(a, b, message);
         }
-
-        assertEquals(a, b, message);
     }
 
     // eg.. <ValueWithTypeDto type="string"><com:string>anotherString</com:string></ValueWithTypeDto>
diff --git a/valuetypes/jodatime/integration/src/main/java/org/apache/isis/valuetypes/jodatime/integration/valuesemantics/JodaDateTimeValueSemantics.java b/valuetypes/jodatime/integration/src/main/java/org/apache/isis/valuetypes/jodatime/integration/valuesemantics/JodaDateTimeValueSemantics.java
index f91f1a0..274d70d 100644
--- a/valuetypes/jodatime/integration/src/main/java/org/apache/isis/valuetypes/jodatime/integration/valuesemantics/JodaDateTimeValueSemantics.java
+++ b/valuetypes/jodatime/integration/src/main/java/org/apache/isis/valuetypes/jodatime/integration/valuesemantics/JodaDateTimeValueSemantics.java
@@ -28,14 +28,14 @@ import org.springframework.stereotype.Component;
 
 import org.apache.isis.applib.value.semantics.ValueSemanticsAbstract;
 import org.apache.isis.core.metamodel.valuesemantics.temporal.ZonedDateTimeValueSemantics;
-import org.apache.isis.core.metamodel.valuetypes.ValueSemanticsAdapter;
+import org.apache.isis.core.metamodel.valuetypes.TemporalSemanticsAdapter;
 import org.apache.isis.schema.common.v2.ValueType;
 import org.apache.isis.valuetypes.jodatime.applib.value.JodatimeConverters;
 
 @Component
 @Named("isis.val.JodaDateTimeValueSemantics")
 public class JodaDateTimeValueSemantics
-extends ValueSemanticsAdapter<org.joda.time.DateTime, ZonedDateTime>  {
+extends TemporalSemanticsAdapter<org.joda.time.DateTime, ZonedDateTime>  {
 
     @Inject ZonedDateTimeValueSemantics zonedDateTimeValueSemantics;
 
diff --git a/valuetypes/jodatime/integration/src/main/java/org/apache/isis/valuetypes/jodatime/integration/valuesemantics/JodaLocalDateTimeValueSemantics.java b/valuetypes/jodatime/integration/src/main/java/org/apache/isis/valuetypes/jodatime/integration/valuesemantics/JodaLocalDateTimeValueSemantics.java
index f9bd2a3..543d0b5 100644
--- a/valuetypes/jodatime/integration/src/main/java/org/apache/isis/valuetypes/jodatime/integration/valuesemantics/JodaLocalDateTimeValueSemantics.java
+++ b/valuetypes/jodatime/integration/src/main/java/org/apache/isis/valuetypes/jodatime/integration/valuesemantics/JodaLocalDateTimeValueSemantics.java
@@ -25,14 +25,14 @@ import org.springframework.stereotype.Component;
 
 import org.apache.isis.applib.value.semantics.ValueSemanticsAbstract;
 import org.apache.isis.core.metamodel.valuesemantics.temporal.LocalDateTimeValueSemantics;
-import org.apache.isis.core.metamodel.valuetypes.ValueSemanticsAdapter;
+import org.apache.isis.core.metamodel.valuetypes.TemporalSemanticsAdapter;
 import org.apache.isis.schema.common.v2.ValueType;
 import org.apache.isis.valuetypes.jodatime.applib.value.JodatimeConverters;
 
 @Component
 @Named("isis.val.JodaLocalDateTimeValueSemantics")
 public class JodaLocalDateTimeValueSemantics
-extends ValueSemanticsAdapter<org.joda.time.LocalDateTime, java.time.LocalDateTime>  {
+extends TemporalSemanticsAdapter<org.joda.time.LocalDateTime, java.time.LocalDateTime>  {
 
     @Inject LocalDateTimeValueSemantics localDateTimeValueSemantics;
 
diff --git a/valuetypes/jodatime/integration/src/main/java/org/apache/isis/valuetypes/jodatime/integration/valuesemantics/JodaLocalDateValueSemantics.java b/valuetypes/jodatime/integration/src/main/java/org/apache/isis/valuetypes/jodatime/integration/valuesemantics/JodaLocalDateValueSemantics.java
index 4a4019d..5281048 100644
--- a/valuetypes/jodatime/integration/src/main/java/org/apache/isis/valuetypes/jodatime/integration/valuesemantics/JodaLocalDateValueSemantics.java
+++ b/valuetypes/jodatime/integration/src/main/java/org/apache/isis/valuetypes/jodatime/integration/valuesemantics/JodaLocalDateValueSemantics.java
@@ -25,14 +25,14 @@ import org.springframework.stereotype.Component;
 
 import org.apache.isis.applib.value.semantics.ValueSemanticsAbstract;
 import org.apache.isis.core.metamodel.valuesemantics.temporal.LocalDateValueSemantics;
-import org.apache.isis.core.metamodel.valuetypes.ValueSemanticsAdapter;
+import org.apache.isis.core.metamodel.valuetypes.TemporalSemanticsAdapter;
 import org.apache.isis.schema.common.v2.ValueType;
 import org.apache.isis.valuetypes.jodatime.applib.value.JodatimeConverters;
 
 @Component
 @Named("isis.val.JodaLocalDateValueSemantics")
 public class JodaLocalDateValueSemantics
-extends ValueSemanticsAdapter<org.joda.time.LocalDate, java.time.LocalDate>  {
+extends TemporalSemanticsAdapter<org.joda.time.LocalDate, java.time.LocalDate>  {
 
     @Inject LocalDateValueSemantics localDateValueSemantics;
 
diff --git a/valuetypes/jodatime/integration/src/main/java/org/apache/isis/valuetypes/jodatime/integration/valuesemantics/JodaLocalTimeValueSemantics.java b/valuetypes/jodatime/integration/src/main/java/org/apache/isis/valuetypes/jodatime/integration/valuesemantics/JodaLocalTimeValueSemantics.java
index 778f1c2..1815a4e 100644
--- a/valuetypes/jodatime/integration/src/main/java/org/apache/isis/valuetypes/jodatime/integration/valuesemantics/JodaLocalTimeValueSemantics.java
+++ b/valuetypes/jodatime/integration/src/main/java/org/apache/isis/valuetypes/jodatime/integration/valuesemantics/JodaLocalTimeValueSemantics.java
@@ -25,14 +25,14 @@ import org.springframework.stereotype.Component;
 
 import org.apache.isis.applib.value.semantics.ValueSemanticsAbstract;
 import org.apache.isis.core.metamodel.valuesemantics.temporal.LocalTimeValueSemantics;
-import org.apache.isis.core.metamodel.valuetypes.ValueSemanticsAdapter;
+import org.apache.isis.core.metamodel.valuetypes.TemporalSemanticsAdapter;
 import org.apache.isis.schema.common.v2.ValueType;
 import org.apache.isis.valuetypes.jodatime.applib.value.JodatimeConverters;
 
 @Component
 @Named("isis.val.JodaLocalTimeValueSemantics")
 public class JodaLocalTimeValueSemantics
-extends ValueSemanticsAdapter<org.joda.time.LocalTime, java.time.LocalTime>  {
+extends TemporalSemanticsAdapter<org.joda.time.LocalTime, java.time.LocalTime>  {
 
     @Inject LocalTimeValueSemantics localTimeValueSemantics;