Repository: jena
Updated Branches:
  refs/heads/master 7f2dfed0a -> edba13136




First implementation of fn:adjust-dateTime-to-timezone.

Project: http://git-wip-us.apache.org/repos/asf/jena/repo
Commit: http://git-wip-us.apache.org/repos/asf/jena/commit/da73e967
Tree: http://git-wip-us.apache.org/repos/asf/jena/tree/da73e967
Diff: http://git-wip-us.apache.org/repos/asf/jena/diff/da73e967

Branch: refs/heads/master
Commit: da73e967b19f00f4d5f8b245079b9894331715db
Parents: f2ae5db
Author: ales004 <[email protected]>
Authored: Sun May 29 19:13:47 2016 +0200
Committer: ales004 <[email protected]>
Committed: Sun May 29 19:13:47 2016 +0200

----------------------------------------------------------------------
 .../jena/sparql/expr/nodevalue/XSDFuncOp.java   | 61 +++++++++++++++++---
 .../jena/sparql/function/StandardFunctions.java |  1 +
 .../library/FN_AdjustDatetimeToTimezone.java    | 55 ++++++++++++++++++
 .../apache/jena/sparql/expr/TestFunctions.java  | 38 +++++++++++-
 4 files changed, 147 insertions(+), 8 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/jena/blob/da73e967/jena-arq/src/main/java/org/apache/jena/sparql/expr/nodevalue/XSDFuncOp.java
----------------------------------------------------------------------
diff --git 
a/jena-arq/src/main/java/org/apache/jena/sparql/expr/nodevalue/XSDFuncOp.java 
b/jena-arq/src/main/java/org/apache/jena/sparql/expr/nodevalue/XSDFuncOp.java
index 817c20f..8b31d92 100644
--- 
a/jena-arq/src/main/java/org/apache/jena/sparql/expr/nodevalue/XSDFuncOp.java
+++ 
b/jena-arq/src/main/java/org/apache/jena/sparql/expr/nodevalue/XSDFuncOp.java
@@ -34,10 +34,7 @@ import static 
org.apache.jena.sparql.expr.nodevalue.NumericType.OP_INTEGER ;
 import java.math.BigDecimal ;
 import java.math.BigInteger ;
 import java.text.Normalizer;
-import java.util.ArrayList;
-import java.util.HashSet ;
-import java.util.List ;
-import java.util.Set ;
+import java.util.*;
 import java.util.regex.Matcher ;
 import java.util.regex.Pattern ;
 
@@ -1426,10 +1423,9 @@ public class XSDFuncOp
         return NodeValue.makeString(dts.timezone) ;
     }
 
-    public static NodeValue dtGetTimezone(NodeValue nv) {
-        DateTimeStruct dts = parseAnyDT(nv) ;
+    private static NodeValue fromTimezoneToDuration(DateTimeStruct dts){
         if ( dts == null || dts.timezone == null )
-            throw new ExprEvalException("Not a datatype with a timezone: " + 
nv) ;
+            return null;
         if ( "".equals(dts.timezone) )
             return null ;
         if ( "Z".equals(dts.timezone) ) {
@@ -1460,6 +1456,13 @@ public class XSDFuncOp
         return NodeValue.makeNode(sb.toString(), null, XSDDatatype.XSD + 
"#dayTimeDuration") ;
     }
 
+    public static NodeValue dtGetTimezone(NodeValue nv) {
+        DateTimeStruct dts = parseAnyDT(nv) ;
+        if ( dts == null || dts.timezone == null )
+            throw new ExprEvalException("Not a datatype with a timezone: " + 
nv) ;
+        return fromTimezoneToDuration(dts);
+    }
+
     private static void digitsTwo(String s, int idx, StringBuilder sb, char 
indicator) {
         if ( s.charAt(idx) == '0' ) {
             idx++ ;
@@ -1554,4 +1557,48 @@ public class XSDFuncOp
 //            dur = ... 
         return dur ;
     }
+
+    public static NodeValue adjustDatetimeToTimezone(NodeValue nv1,NodeValue 
nv2){
+        if(nv1 == null)
+            return null;
+
+        if(!nv1.isDateTime() && !nv1.isDate()){
+            throw new ExprEvalException("Not a valid date or datetime:"+nv1);
+        }
+        DateTimeStruct dts = parseAnyDT(nv1);
+        NodeValue inputTimezone = fromTimezoneToDuration(dts);
+        Boolean hasTz = inputTimezone == null ? false : true;
+        XMLGregorianCalendar calValue = nv1.getDateTime();
+        int inputOffset = 0;
+        if(hasTz){
+            Duration inputDuration = inputTimezone.getDuration();
+            inputOffset = inputDuration.getSign()*(inputDuration.getMinutes() 
+ 60*inputDuration.getHours());
+        }
+
+        int tzOffset = TimeZone.getDefault().getRawOffset() / (1000*60);
+        if(nv2 != null){
+            if(!nv2.isDuration()) {
+                String nv2StrValue = nv2.getString();
+                if(nv2StrValue.equals("")){
+                    calValue.setTimezone(DatatypeConstants.FIELD_UNDEFINED);
+                    if(nv1.isDateTime())
+                        return NodeValue.makeDateTime(calValue);
+                    else
+                        return NodeValue.makeDate(calValue);
+                }
+                throw new ExprEvalException("Not a valid duration:" + nv2);
+            }
+            Duration tzDuration = nv2.getDuration();
+            tzOffset = tzDuration.getSign()*(tzDuration.getMinutes() + 
60*tzDuration.getHours());
+        }
+        String tzSign = (tzOffset-inputOffset) > 0 ? "" : "-";
+        Duration durToAdd = 
NodeValue.makeDuration(tzSign+"PT"+java.lang.Math.abs(tzOffset-inputOffset)+"M").getDuration();
+        if(hasTz)
+            calValue.add(durToAdd);
+        calValue.setTimezone(tzOffset);
+        if(nv1.isDateTime())
+            return NodeValue.makeDateTime(calValue);
+        else
+            return NodeValue.makeDate(calValue);
+    }
 }

http://git-wip-us.apache.org/repos/asf/jena/blob/da73e967/jena-arq/src/main/java/org/apache/jena/sparql/function/StandardFunctions.java
----------------------------------------------------------------------
diff --git 
a/jena-arq/src/main/java/org/apache/jena/sparql/function/StandardFunctions.java 
b/jena-arq/src/main/java/org/apache/jena/sparql/function/StandardFunctions.java
index 9594059..e8b014d 100644
--- 
a/jena-arq/src/main/java/org/apache/jena/sparql/function/StandardFunctions.java
+++ 
b/jena-arq/src/main/java/org/apache/jena/sparql/function/StandardFunctions.java
@@ -164,6 +164,7 @@ public class StandardFunctions
         
         // XQ/XP 3.
 //        9.6.1 fn:adjust-dateTime-to-timezone
+        add(registry, xfn+"adjust-dateTime-to-timezone",  
FN_AdjustDatetimeToTimezone.class) ;
 //        9.6.2 fn:adjust-date-to-timezone
 //        9.6.3 fn:adjust-time-to-timezone
 //        9.8.1 fn:format-dateTime

http://git-wip-us.apache.org/repos/asf/jena/blob/da73e967/jena-arq/src/main/java/org/apache/jena/sparql/function/library/FN_AdjustDatetimeToTimezone.java
----------------------------------------------------------------------
diff --git 
a/jena-arq/src/main/java/org/apache/jena/sparql/function/library/FN_AdjustDatetimeToTimezone.java
 
b/jena-arq/src/main/java/org/apache/jena/sparql/function/library/FN_AdjustDatetimeToTimezone.java
new file mode 100644
index 0000000..7d480dd
--- /dev/null
+++ 
b/jena-arq/src/main/java/org/apache/jena/sparql/function/library/FN_AdjustDatetimeToTimezone.java
@@ -0,0 +1,55 @@
+/*
+ * 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.jena.sparql.function.library;
+
+import org.apache.jena.atlas.lib.Lib;
+import org.apache.jena.query.QueryBuildException;
+import org.apache.jena.sparql.expr.ExprEvalException;
+import org.apache.jena.sparql.expr.ExprList;
+import org.apache.jena.sparql.expr.NodeValue;
+import org.apache.jena.sparql.expr.nodevalue.XSDFuncOp;
+import org.apache.jena.sparql.function.FunctionBase;
+
+import java.util.List;
+
+public class FN_AdjustDatetimeToTimezone extends FunctionBase {
+    public FN_AdjustDatetimeToTimezone(){super();}
+
+    @Override
+    public void checkBuild(String uri, ExprList args)
+    {
+        if ( args.size() != 1 && args.size() != 2 )
+            throw new QueryBuildException("Function '"+ Lib.className(this)+"' 
takes one or two arguments") ;
+    }
+    @Override
+    public NodeValue exec(List<NodeValue> args)
+    {
+        if ( args.size() != 1 && args.size() != 2 )
+            throw new ExprEvalException("FN_StrNormalizeUnicode: Wrong number 
of arguments: "+args.size()+" : [wanted 1 or 2]") ;
+
+        NodeValue v1 = args.get(0) ;
+
+        if ( args.size() == 2 )
+        {
+            NodeValue v2 = args.get(1) ;
+            return XSDFuncOp.adjustDatetimeToTimezone(v1, v2) ;
+        }
+
+        return XSDFuncOp.adjustDatetimeToTimezone(v1, null) ;
+    }
+}

http://git-wip-us.apache.org/repos/asf/jena/blob/da73e967/jena-arq/src/test/java/org/apache/jena/sparql/expr/TestFunctions.java
----------------------------------------------------------------------
diff --git 
a/jena-arq/src/test/java/org/apache/jena/sparql/expr/TestFunctions.java 
b/jena-arq/src/test/java/org/apache/jena/sparql/expr/TestFunctions.java
index 589c9c4..3864711 100644
--- a/jena-arq/src/test/java/org/apache/jena/sparql/expr/TestFunctions.java
+++ b/jena-arq/src/test/java/org/apache/jena/sparql/expr/TestFunctions.java
@@ -348,6 +348,35 @@ public class TestFunctions
     // counter-intuitive -- would fail if float/double not translated to 
decimal
     @Test public void exprRoundHalfEven_08()    { 
test("fn:round-half-to-even('150.015'^^xsd:float, 2)",     
NodeValue.makeFloat((float)150.01)) ; }
 
+    private String getDynamicDurationString(){
+        int tzOffset = TimeZone.getDefault().getRawOffset() / (1000*60);
+        return "PT"+tzOffset+"M";
+    }
+
+    @Test public void exprAdjustDatetimeToTz_01(){
+        testEqual(
+                
"fn:adjust-dateTime-to-timezone('2002-03-07T10:00:00'^^xsd:dateTime)",
+                
"fn:adjust-dateTime-to-timezone('2002-03-07T10:00:00'^^xsd:dateTime,'"+getDynamicDurationString()+"'^^xsd:dayTimeDuration)");
+    }
+
+    @Test public void exprAdjustDatetimeToTz_02(){
+        testEqual(
+                
"fn:adjust-dateTime-to-timezone('2002-03-07T10:00:00-07:00'^^xsd:dateTime)",
+                
"fn:adjust-dateTime-to-timezone('2002-03-07T10:00:00-07:00'^^xsd:dateTime,'"+getDynamicDurationString()+"'^^xsd:dayTimeDuration)");
+    }
+
+    @Test public void 
exprAdjustDatetimeToTz_03(){test("fn:adjust-dateTime-to-timezone('2002-03-07T10:00:00'^^xsd:dateTime,'-PT10H'^^xsd:dayTimeDuration)",NodeValue.makeDateTime("2002-03-07T10:00:00-10:00"));}
+
+    @Test public void 
exprAdjustDatetimeToTz_04(){test("fn:adjust-dateTime-to-timezone('2002-03-07T10:00:00-07:00'^^xsd:dateTime,'-PT10H'^^xsd:dayTimeDuration)",NodeValue.makeDateTime("2002-03-07T07:00:00-10:00"));}
+
+    @Test public void 
exprAdjustDatetimeToTz_05(){test("fn:adjust-dateTime-to-timezone('2002-03-07T10:00:00-07:00'^^xsd:dateTime,'PT10H'^^xsd:dayTimeDuration)",NodeValue.makeDateTime("2002-03-08T03:00:00+10:00"));}
+
+    @Test public void 
exprAdjustDatetimeToTz_06(){test("fn:adjust-dateTime-to-timezone('2002-03-07T00:00:00+01:00'^^xsd:dateTime,'-PT8H'^^xsd:dayTimeDuration)",NodeValue.makeDateTime("2002-03-06T15:00:00-08:00"));}
+
+    @Test public void 
exprAdjustDatetimeToTz_07(){test("fn:adjust-dateTime-to-timezone('2002-03-07T10:00:00'^^xsd:dateTime,'')",NodeValue.makeDateTime("2002-03-07T10:00:00"));}
+
+    @Test public void 
exprAdjustDatetimeToTz_08(){test("fn:adjust-dateTime-to-timezone('2002-03-07T10:00:00-07:00'^^xsd:dateTime,'')",NodeValue.makeDateTime("2002-03-07T10:00:00"));}
+
     //@Test public void exprStrJoin()      { test("fn:string-join('a', 'b')", 
NodeValue.makeString("ab")) ; }
     
     @Test public void exprSameTerm1()     { test("sameTerm(1,1)",           
TRUE) ; }
@@ -402,7 +431,14 @@ public class TestFunctions
         NodeValue r = expr.eval(null, FunctionEnvBase.createTest()) ;
         assertEquals(result, r) ;
     }
-    
+
+    private void testEqual(String exprStr, String exprStrExpected)
+    {
+        Expr expr = ExprUtils.parse(exprStrExpected) ;
+        NodeValue rExpected = expr.eval(null, FunctionEnvBase.createTest()) ;
+        test(exprStr,rExpected);
+    }
+
     private void testEvalException(String exprStr)
     {
         Expr expr = ExprUtils.parse(exprStr) ;

Reply via email to