You are viewing a plain text version of this content. The canonical link for it is here.
Posted to pr@jena.apache.org by "afs (via GitHub)" <gi...@apache.org> on 2024/02/18 10:53:15 UTC

Re: [PR] GH-2273: XSD Duration division [jena]

afs commented on code in PR #2274:
URL: https://github.com/apache/jena/pull/2274#discussion_r1493737081


##########
jena-arq/src/main/java/org/apache/jena/sparql/expr/nodevalue/NodeValueOps.java:
##########
@@ -230,22 +177,71 @@ public static NodeValue multiplicationNV(NodeValue nv1, NodeValue nv2) {
                 throw new ExprEvalTypeException("Operator '*': only dayTime duration.  Got: " + nv1);
             BigDecimal dec = nv2.getDecimal();
             Duration r = dur.multiply(dec);
-            Node n = NodeFactoryExtra.createLiteralNode(r.toString(), null, dtXSDdayTimeDuration);
+            Node n = NodeFactory.createLiteral(r.toString(), XSDDatatype.XSDduration);
             return NodeValue.makeNodeDuration(r, n);
         }
         throw new ExprEvalTypeException("Operator '*' : Undefined multiply: " + nv1 + " and " + nv2);
     }
 
+    /** Divide two {@link NodeValue NodeValues}, with all the extra datatypes and extensions supported. */
     public static NodeValue divisionNV(NodeValue nv1, NodeValue nv2) {
         ValueSpace vs1 = nv1.getValueSpace();
         ValueSpace vs2 = nv2.getValueSpace();
 
         if ( vs1.equals(VSPACE_NUM) && vs2.equals(VSPACE_NUM) )
             return XSDFuncOp.numDivide(nv1, nv2);
 
+        // Duration divided by number
+        if ( vs1.equals(VSPACE_DURATION) && vs2.equals(VSPACE_NUM) ) {
+            Duration dur = nv1.getDuration();
+            // Multiply by 1/number.
+            BigDecimal dec = nv2.getDecimal();
+            BigDecimal dec1 = BigDecimal.ONE.divide(dec);
+            Duration r = dur.multiply(dec1);
+            // Should normalize but not Duration.normalizeWith for a general duration.
+            // DT or YM specific normalization could be done. e.g. days can go over 31.
+            Node n = NodeFactory.createLiteral(r.toString(), XSDDatatype.XSDduration);
+            return NodeValue.makeNodeDuration(r, n);
+        }
+
+        // Duration divided by duration
+        if ( vs1.equals(VSPACE_DURATION) && vs2.equals(VSPACE_DURATION) ) {
+            // Ratio as a BigDecimal
+            Duration dur1 = nv1.getDuration();
+            Duration dur2 = nv2.getDuration();
+            if ( XSDFuncOp.isDayTime(dur1) && XSDFuncOp.isDayTime(dur2) ) {
+                // In seconds. Ignores fractional seconds.
+                double x1 = durationDayTimeAsSeconds(dur1);
+                double x2 = durationDayTimeAsSeconds(dur2);
+                return NodeValue.makeDecimal(x1/x2);

Review Comment:
   Done. 
   
   With tests.
   
   (An exception from a function evaluation is caught anyway but having code for this case in the function itslef does make for a clearer error message.)



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: pr-unsubscribe@jena.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: pr-unsubscribe@jena.apache.org
For additional commands, e-mail: pr-help@jena.apache.org