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

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


The following commit(s) were added to refs/heads/master by this push:
     new 8c09eb0  JENA-1659: fn:implicit-timezone(), afn:timezone, afn:nowtz().
     new c5fc4e6  Merge pull request #523 from afs/timezone
8c09eb0 is described below

commit 8c09eb00062f896c47e524dde154db882aa356bc
Author: Andy Seaborne <[email protected]>
AuthorDate: Mon Jan 21 11:08:45 2019 +0000

    JENA-1659: fn:implicit-timezone(), afn:timezone, afn:nowtz().
    
    Move test support function out of main/FunctionEndBase into
    test/LibTestExpr.
    
    Clearing up while visiting.
---
 .../java/org/apache/jena/sparql/SystemARQ.java     |  6 +-
 .../org/apache/jena/sparql/expr/NodeValue.java     | 10 +--
 .../jena/sparql/expr/nodevalue/NodeFunctions.java  | 39 ++++++++-
 .../jena/sparql/expr/nodevalue/XSDFuncOp.java      | 45 +++++-----
 .../org/apache/jena/sparql/function/CastXSD.java   |  1 -
 .../jena/sparql/function/FunctionEnvBase.java      |  6 --
 .../jena/sparql/function/StandardFunctions.java    |  6 +-
 .../jena/sparql/function/library/FN_Timezone.java  | 35 ++++++++
 .../jena/sparql/function/library/SystemVar.java    | 61 ++++++--------
 .../apache/jena/sparql/function/library/nowtz.java | 95 ++++++++++++++++++++++
 .../jena/sparql/function/library/timezone.java     | 22 +++++
 .../org/apache/jena/sparql/expr/LibTestExpr.java   | 11 +++
 .../apache/jena/sparql/expr/TestExpressions2.java  |  6 +-
 .../apache/jena/sparql/expr/TestExpressions3.java  |  5 +-
 .../org/apache/jena/sparql/expr/TestFunctions.java | 62 ++++++++------
 .../function/user/TestFunctionExpansion.java       |  8 +-
 .../function/user/TestFunctionNonExpansion.java    |  8 +-
 17 files changed, 303 insertions(+), 123 deletions(-)

diff --git a/jena-arq/src/main/java/org/apache/jena/sparql/SystemARQ.java 
b/jena-arq/src/main/java/org/apache/jena/sparql/SystemARQ.java
index 27a96aa..a77a64b 100644
--- a/jena-arq/src/main/java/org/apache/jena/sparql/SystemARQ.java
+++ b/jena-arq/src/main/java/org/apache/jena/sparql/SystemARQ.java
@@ -42,10 +42,10 @@ public class SystemARQ
     // Various system wide settings, "constants" that might change e.g. test 
setups
     // ** This can be loaded before the rest of ARQ is initialized **
 
-    // NodeValues work without the context so somethings only have global 
settings.
+    // NodeValues work without the context so some things only have global 
settings.
     
-    /** Control whether additon datatypes, over and above strict, minimal 
SPARQL compliance, are handled.
-     *  Examples incldue xsd;date and simple literal/xsd:string.
+    /** Control whether addition datatypes, over and above strict, minimal 
SPARQL compliance, are handled.
+     *  Examples include xsd:date and simple literal/xsd:string.
      */
     public static boolean ValueExtensions       = true ;
 
diff --git a/jena-arq/src/main/java/org/apache/jena/sparql/expr/NodeValue.java 
b/jena-arq/src/main/java/org/apache/jena/sparql/expr/NodeValue.java
index d1c2317..e6c54c1 100644
--- a/jena-arq/src/main/java/org/apache/jena/sparql/expr/NodeValue.java
+++ b/jena-arq/src/main/java/org/apache/jena/sparql/expr/NodeValue.java
@@ -115,9 +115,6 @@ public abstract class NodeValue extends ExprNode
     public static boolean VerboseWarnings = true ;
     public static boolean VerboseExceptions = false ;
     
-    public static final BigInteger IntegerZERO = BigInteger.ZERO ;
-    public static final BigDecimal DecimalZERO = BigDecimal.ZERO ;
-
     public static final NodeValue TRUE   = NodeValue.makeNode("true", 
XSDboolean) ;
     public static final NodeValue FALSE  = NodeValue.makeNode("false", 
XSDboolean) ;
     
@@ -1041,28 +1038,23 @@ public abstract class NodeValue extends ExprNode
             }
 
             if ( (datatype.equals(XSDdateTime) || 
datatype.equals(XSDdateTimeStamp)) && XSDdateTime.isValid(lex) ) {
-                XSDDateTime dateTime = (XSDDateTime)lit.getValue() ;
                 return new NodeValueDT(lex, node) ;
             }
 
             if ( datatype.equals(XSDdate) && XSDdate.isValidLiteral(lit) ) {
                 // Jena datatype support works on masked dataTimes.
-                XSDDateTime dateTime = (XSDDateTime)lit.getValue() ;
+                //XSDDateTime dateTime = (XSDDateTime)lit.getValue() ;
                 return new NodeValueDT(lex, node) ;
             }
 
             if ( datatype.equals(XSDtime) && XSDtime.isValidLiteral(lit) ) {
-                // Jena datatype support works on masked dataTimes.
-                XSDDateTime time = (XSDDateTime)lit.getValue() ;
                 return new NodeValueDT(lex, node) ;
             }
 
             if ( datatype.equals(XSDgYear) && XSDgYear.isValidLiteral(lit) ) {
-                XSDDateTime time = (XSDDateTime)lit.getValue() ;
                 return new NodeValueDT(lex, node) ;
             }
             if ( datatype.equals(XSDgYearMonth) && 
XSDgYearMonth.isValidLiteral(lit) ) {
-                XSDDateTime time = (XSDDateTime)lit.getValue() ;
                 return new NodeValueDT(lex, node) ;
             }
             if ( datatype.equals(XSDgMonth) && XSDgMonth.isValidLiteral(lit) ) 
{
diff --git 
a/jena-arq/src/main/java/org/apache/jena/sparql/expr/nodevalue/NodeFunctions.java
 
b/jena-arq/src/main/java/org/apache/jena/sparql/expr/nodevalue/NodeFunctions.java
index a7cb286..23b7c65 100644
--- 
a/jena-arq/src/main/java/org/apache/jena/sparql/expr/nodevalue/NodeFunctions.java
+++ 
b/jena-arq/src/main/java/org/apache/jena/sparql/expr/nodevalue/NodeFunctions.java
@@ -18,9 +18,15 @@
 
 package org.apache.jena.sparql.expr.nodevalue ;
 
+import java.math.BigDecimal;
+import java.math.BigInteger;
 import java.util.Iterator ;
 import java.util.UUID ;
 
+import javax.xml.datatype.DatatypeConstants;
+import javax.xml.datatype.Duration;
+import javax.xml.datatype.DatatypeConstants.Field;
+
 import org.apache.jena.atlas.logging.Log ;
 import org.apache.jena.datatypes.xsd.XSDDatatype ;
 import org.apache.jena.graph.Node ;
@@ -496,5 +502,36 @@ public class NodeFunctions {
             throw new ExprEvalException("Empty lang tag") ;
         return NodeValue.makeLangString(lex, lang) ;
     }
-
+    
+    /** A duration, tided */ 
+    public static Duration duration(int seconds) {
+        if ( seconds == 0 )
+            return XSDFuncOp.zeroDuration;
+        Duration dur = NodeValue.xmlDatatypeFactory.newDuration(1000*seconds);
+        // Neaten the duration. Not all the fields ar zero.
+        dur = NodeValue.xmlDatatypeFactory.newDuration(dur.getSign()>=0, 
+                                                       field(dur, 
DatatypeConstants.YEARS), 
+                                                       field(dur, 
DatatypeConstants.MONTHS),
+                                                       field(dur, 
DatatypeConstants.DAYS),
+                                                       field(dur, 
DatatypeConstants.HOURS),
+                                                       field(dur, 
DatatypeConstants.MINUTES),
+                                                       field2(dur, 
DatatypeConstants.SECONDS));
+        return dur;
+    }
+
+    //Don't set field if zero.
+    private static BigInteger field(Duration dur, Field field) {
+        BigInteger i = (BigInteger)dur.getField(field);
+        if ( i == null || i.equals(BigInteger.ZERO) )
+            return null;
+        return i;
+    }
+
+    private static BigDecimal field2(Duration dur, Field field) {
+        BigDecimal x = (BigDecimal)dur.getField(field);
+        //x = x.setScale(0);
+        if ( x.compareTo(BigDecimal.ZERO) == 0 )
+            return null;
+        return x;
+    }
 }
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 80dfa7b..91feb0e 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
@@ -37,6 +37,7 @@ import java.text.DecimalFormat ;
 import java.text.DecimalFormatSymbols ;
 import java.text.Normalizer;
 import java.text.NumberFormat ;
+import java.time.ZonedDateTime;
 import java.util.*;
 import java.util.regex.Matcher ;
 import java.util.regex.Pattern ;
@@ -230,9 +231,9 @@ public class XSDFuncOp
             // Plain literals.
             return ! nv.getString().isEmpty() ;
         if ( nv.isInteger() )
-            return !nv.getInteger().equals(NodeValue.IntegerZERO) ;
+            return !nv.getInteger().equals(BigInteger.ZERO) ;
         if ( nv.isDecimal() )
-            return !nv.getDecimal().equals(NodeValue.DecimalZERO) ;
+            return !nv.getDecimal().equals(BigDecimal.ZERO) ;
         if ( nv.isDouble() )
             return nv.getDouble() != 0.0 ;
         NodeValue.raise(new ExprEvalException("Not a boolean effective value 
(wrong type): " + nv)) ;
@@ -1542,7 +1543,7 @@ public class XSDFuncOp
     }
 
     private static NodeValue accessDuration(NodeValue nv, Field field) {
-        Duration dur = valueCanonicalDuration(nv) ;
+        Duration dur = nv.getDuration();
         // if ( ! nv.isDuration() )
         // throw new ExprEvalException("Not a duration: "+nv) ;
         Number x = dur.getField(field) ;
@@ -1558,34 +1559,28 @@ public class XSDFuncOp
         return NodeValue.makeInteger((BigInteger)x) ;
     }
     
-    private static Duration zeroDuration = 
NodeValue.xmlDatatypeFactory.newDuration(0) ;
-    private static Duration valueCanonicalDuration(NodeValue nv) {
-        // Unclear.
-        /* This semi-normalizes a duration value - the time part is normalized.
-         * Maybe > 24 hours -> set days, but not done here.
-         * Because months are variable, XSD F&O does not define 
-         */
-        // TODO - note that the accessors return 0 for unset fields.
-        Duration dur = nv.getDuration() ;
-//        Number xHours = dur.getField(DatatypeConstants.HOURS) ;
-//        Number xMins = dur.getField(DatatypeConstants.MINUTES) ;
-//        Number xSeconds = dur.getField(DatatypeConstants.SECONDS) ;
-//        boolean normalize = 
-//            ( xHours == null || xHours.longValue() >= 24 ) ||  
-//            ( xMins == null || xMins.longValue() >= 60 ) ||
-//            ( xSeconds == null || xSeconds.longValue() >= 60 ) ;
-//        if ( normalize )
-//            dur = ... 
-        return dur ;
+    public static Duration zeroDuration = 
NodeValue.xmlDatatypeFactory.newDuration(true, null, null, null, null, null, 
BigDecimal.ZERO) ;
+    
+    public static NodeValue localTimezone() {
+        Duration dur = localTimezoneDuration();
+        NodeValue nv = NodeValue.makeDuration(dur);
+        return nv;
     }
-
+    
+    /** Local (query engine) timezone including DST */ 
+    private static Duration localTimezoneDuration() {
+        ZonedDateTime zdt = ZonedDateTime.now();
+        int tzDurationInSeconds = zdt.getOffset().getTotalSeconds();
+        Duration dur = NodeFunctions.duration(tzDurationInSeconds);
+        return dur; 
+    }
+    
     public static NodeValue adjustDatetimeToTimezone(NodeValue nv1,NodeValue 
nv2){
         if(nv1 == null)
             return null;
 
-        if(!nv1.isDateTime() && !nv1.isDate() && !nv1.isTime()){
+        if(!nv1.isDateTime() && !nv1.isDate() && !nv1.isTime())
             throw new ExprEvalException("Not a valid date, datetime or 
time:"+nv1);
-        }
 
         XMLGregorianCalendar calValue = nv1.getDateTime();
         Boolean hasTz = calValue.getTimezone() != 
DatatypeConstants.FIELD_UNDEFINED;
diff --git 
a/jena-arq/src/main/java/org/apache/jena/sparql/function/CastXSD.java 
b/jena-arq/src/main/java/org/apache/jena/sparql/function/CastXSD.java
index 8919334..806d092 100644
--- a/jena-arq/src/main/java/org/apache/jena/sparql/function/CastXSD.java
+++ b/jena-arq/src/main/java/org/apache/jena/sparql/function/CastXSD.java
@@ -143,7 +143,6 @@ public class CastXSD extends FunctionBase1 implements 
FunctionFactory {
                     if ( nv.isYearMonthDuration() )
                         return NodeValue.makeNode("PT0S", castType) ;
                     Duration d2 =  NodeValue.xmlDatatypeFactory.newDuration
-                        
                         (d.getSign()>=0,
                         null, null, 
(BigInteger)d.getField(DatatypeConstants.DAYS),
                         (BigInteger)d.getField(DatatypeConstants.HOURS), 
(BigInteger)d.getField(DatatypeConstants.MINUTES), 
(BigDecimal)d.getField(DatatypeConstants.SECONDS)) ;
diff --git 
a/jena-arq/src/main/java/org/apache/jena/sparql/function/FunctionEnvBase.java 
b/jena-arq/src/main/java/org/apache/jena/sparql/function/FunctionEnvBase.java
index c531fce..ae62a12 100644
--- 
a/jena-arq/src/main/java/org/apache/jena/sparql/function/FunctionEnvBase.java
+++ 
b/jena-arq/src/main/java/org/apache/jena/sparql/function/FunctionEnvBase.java
@@ -33,12 +33,6 @@ public class FunctionEnvBase implements FunctionEnv
     private DatasetGraph dataset ;
     private ExecutionContext execContext = null ;
 
-    /** Create an execution environment suitable for testing functions and 
expressions */ 
-    public static FunctionEnv createTest()
-    {
-        return new FunctionEnvBase(ARQ.getContext()) ;
-    }
-    
     public FunctionEnvBase() { this(ARQ.getContext(), null, null) ; }
     
     public FunctionEnvBase(Context context) { this ( context, null, null) ; }
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 a4e2662..393c753 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
@@ -198,6 +198,11 @@ public class StandardFunctions
 //        9.8.2 fn:format-date
 //        9.8.3 fn:format-time
         
+        
+//        15.6 fn:implicit-timezone -> xsd:dayTimeDuration
+        add(registry, xfn+"implicit-timezone",  FN_Timezone.class) ;
+        // Also available as afn:timezone.
+        
         // math:
 //        4.8 Trigonometric and exponential functions
 //        4.8.1 math:pi
@@ -241,7 +246,6 @@ public class StandardFunctions
         add(registry, xfn+"apply",           FN_Apply.class);
         add(registry, xfn+"collation-key",   FN_CollationKey.class);
 
-        
         // And add op:'s
 //        4.2.1 op:numeric-add
 //        4.2.2 op:numeric-subtract
diff --git 
a/jena-arq/src/main/java/org/apache/jena/sparql/function/library/FN_Timezone.java
 
b/jena-arq/src/main/java/org/apache/jena/sparql/function/library/FN_Timezone.java
new file mode 100644
index 0000000..a171aa7
--- /dev/null
+++ 
b/jena-arq/src/main/java/org/apache/jena/sparql/function/library/FN_Timezone.java
@@ -0,0 +1,35 @@
+/**
+ * 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.sparql.expr.NodeValue ;
+import org.apache.jena.sparql.expr.nodevalue.XSDFuncOp;
+import org.apache.jena.sparql.function.FunctionBase0;
+
+/**
+ * fn:implicit-timezone
+ */
+public class FN_Timezone extends FunctionBase0
+{
+    @Override
+    public NodeValue exec() {
+        return XSDFuncOp.localTimezone(); 
+    }
+}
+
diff --git 
a/jena-arq/src/main/java/org/apache/jena/sparql/function/library/SystemVar.java 
b/jena-arq/src/main/java/org/apache/jena/sparql/function/library/SystemVar.java
index 97c7431..98af66f 100644
--- 
a/jena-arq/src/main/java/org/apache/jena/sparql/function/library/SystemVar.java
+++ 
b/jena-arq/src/main/java/org/apache/jena/sparql/function/library/SystemVar.java
@@ -18,48 +18,41 @@
 
 package org.apache.jena.sparql.function.library;
 
-import org.apache.jena.atlas.lib.Lib ;
-import org.apache.jena.graph.Node ;
-import org.apache.jena.sparql.engine.binding.Binding ;
-import org.apache.jena.sparql.expr.ExprEvalException ;
-import org.apache.jena.sparql.expr.ExprException ;
-import org.apache.jena.sparql.expr.ExprList ;
-import org.apache.jena.sparql.expr.NodeValue ;
-import org.apache.jena.sparql.function.Function ;
-import org.apache.jena.sparql.function.FunctionEnv ;
-import org.apache.jena.sparql.util.Symbol ;
+import org.apache.jena.atlas.lib.Lib;
+import org.apache.jena.graph.Node;
+import org.apache.jena.sparql.expr.ExprEvalException;
+import org.apache.jena.sparql.expr.ExprException;
+import org.apache.jena.sparql.expr.NodeValue;
+import org.apache.jena.sparql.function.FunctionBase0;
+import org.apache.jena.sparql.function.FunctionEnv;
+import org.apache.jena.sparql.util.Symbol;
 
 /**
  * Function that returns the value of a system variable.
  */
-public class SystemVar implements Function
-{
-    private Symbol systemSymbol ;
-    protected SystemVar(Symbol systemSymbol)
-    {
+public class SystemVar extends FunctionBase0 {
+    private Symbol systemSymbol;
+
+    protected SystemVar(Symbol systemSymbol) {
         if ( systemSymbol == null )
-            throw new ExprException("System symbol is null ptr") ;
-        this.systemSymbol = systemSymbol ;
+            throw new ExprException("System symbol is null ptr");
+        this.systemSymbol = systemSymbol;
     }
-    
+
     // Need to intercept exec so we can get to the FunctionEnv
     @Override
-    public NodeValue exec(Binding binding, ExprList args, String uri, 
FunctionEnv env) {
-        // Ignore arguments.
-        Object obj = env.getContext().get(systemSymbol) ;
-        if ( obj == null )
-            throw new ExprEvalException("null for system symbol: 
"+systemSymbol) ;
-        if ( ! ( obj instanceof Node ) )
-            throw new ExprEvalException("Not a Node: "+Lib.className(obj)) ;
-        
-        Node n = (Node)obj ;
-//        if ( n == null )
-//            throw new ExprEvalException("No value for system variable: 
"+systemSymbol) ;  
-        // NodeValue.makeNode could have a cache.
-        NodeValue nv = NodeValue.makeNode(n) ;
-        return nv ;
+    public NodeValue exec() {
+        return get(systemSymbol, super.functionEnv);
     }
 
-    @Override
-    public void build(String uri, ExprList args) {}
+    public static NodeValue get(Symbol symbol, FunctionEnv env) {
+        Object obj = env.getContext().get(symbol);
+        if ( obj == null )
+            throw new ExprEvalException("null for symbol: " + symbol);
+        if ( !(obj instanceof Node) )
+            throw new ExprEvalException("Not a Node: " + Lib.className(obj));
+        Node n = (Node)obj;
+        NodeValue nv = NodeValue.makeNode(n);
+        return nv;
+    }
 }
diff --git 
a/jena-arq/src/main/java/org/apache/jena/sparql/function/library/nowtz.java 
b/jena-arq/src/main/java/org/apache/jena/sparql/function/library/nowtz.java
new file mode 100644
index 0000000..ba6d387
--- /dev/null
+++ b/jena-arq/src/main/java/org/apache/jena/sparql/function/library/nowtz.java
@@ -0,0 +1,95 @@
+/*
+ * 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 java.time.ZoneId;
+import java.time.ZoneOffset;
+import java.time.ZonedDateTime;
+import java.time.format.DateTimeFormatter;
+
+import org.apache.jena.atlas.lib.DateTimeUtils;
+import org.apache.jena.graph.Node;
+
+//import org.apache.commons.logging.*;
+
+import org.apache.jena.sparql.ARQConstants ;
+import org.apache.jena.sparql.SystemARQ;
+import org.apache.jena.sparql.expr.NodeValue;
+import org.apache.jena.sparql.expr.nodevalue.XSDFuncOp;
+import org.apache.jena.sparql.function.FunctionBase0;
+import org.apache.jena.sparql.util.Context;
+import org.apache.jena.sparql.util.Symbol;
+
+/** Function that accesses the current time and returns in the timezone of the 
query engine. */
+
+public class nowtz extends FunctionBase0
+{
+    public nowtz() { }
+
+    public static Symbol symNowTz = SystemARQ.allocSymbol("nowtz"); 
+
+    @Override
+    public NodeValue exec() {
+        Context cxt = functionEnv.getContext();
+        if ( cxt.isDefined(symNowTz) ) {
+            NodeValue nvx = cxt.get(symNowTz);
+            return nvx; 
+        }
+        NodeValue nvx = execAdjust();
+//        String formattedDate = fromQueryTime(cxt);
+//        NodeValue nvx = NodeValue.makeNode(formattedDate, null, 
XSD.dateTime.getURI());
+        cxt.set(symNowTz, nvx);
+        return nvx;
+    }
+    
+    private NodeValue execAdjust() {
+        // NOW is UTC in Jena to make the same whoever is looking.
+        // For presentation reasons, you may want it in the (server) local 
timezone. 
+        // Calculate:
+        //   fn:adjust-dateTime-to-timezone(NOW(), fn:implicit-timezone())
+        //   fn:adjust-dateTime-to-timezone(NOW(), afn:timezone())
+        
+        // Query time, in UTC. 
+        NodeValue nv = SystemVar.get(ARQConstants.sysCurrentTime, 
super.functionEnv);
+        // Timezone as xsd:dayTimeDuration.
+        NodeValue nvTz = XSDFuncOp.localTimezone();
+        // Comes out as "Z", not "+00:00" because of cal.toXMLFormat() in 
NodeValue.makeDateTime
+        return XSDFuncOp.adjustDatetimeToTimezone(nv, nvTz);
+    }
+    
+    // For information. Do it by accessing the query current time and 
converting using
+    // ZonedDateTime.withZoneSameInstant (from Java8 java.time). 
+
+    private static DateTimeFormatter dtf = 
DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSxxxxx");
+    private static ZoneId zoneIdUTC = ZoneOffset.UTC;
+    
+    private static String fromQueryTime(Context cxt) {
+        // In UTC.
+        Node n = cxt.get(ARQConstants.sysCurrentTime);
+        String x = (n == null) ? DateTimeUtils.nowAsXSDDateTimeString() : 
n.getLiteralLexicalForm();
+        ZonedDateTime zdt = dtf.parse(x, ZonedDateTime::from);
+        ZonedDateTime zdtLocal;
+        // Convert to local timezone. (maybe should put the time into context 
as an Instant?)
+        if ( ! zoneIdUTC.equals(ZoneId.systemDefault()) ) 
+            zdtLocal = zdt.withZoneSameInstant(ZoneId.systemDefault());
+        else
+            zdtLocal = zdt;
+        return dtf.format(zdtLocal);
+    }
+}
diff --git 
a/jena-arq/src/main/java/org/apache/jena/sparql/function/library/timezone.java 
b/jena-arq/src/main/java/org/apache/jena/sparql/function/library/timezone.java
new file mode 100644
index 0000000..1e6408e
--- /dev/null
+++ 
b/jena-arq/src/main/java/org/apache/jena/sparql/function/library/timezone.java
@@ -0,0 +1,22 @@
+/*
+ * 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;
+
+/** Alternative name: afn:timezone for fn:implicit-timezone */
+public class timezone extends FN_Timezone {}
diff --git 
a/jena-arq/src/test/java/org/apache/jena/sparql/expr/LibTestExpr.java 
b/jena-arq/src/test/java/org/apache/jena/sparql/expr/LibTestExpr.java
index 20dec1c..254b74e 100644
--- a/jena-arq/src/test/java/org/apache/jena/sparql/expr/LibTestExpr.java
+++ b/jena-arq/src/test/java/org/apache/jena/sparql/expr/LibTestExpr.java
@@ -19,11 +19,14 @@
 package org.apache.jena.sparql.expr;
 import static org.junit.Assert.* ;
 import org.apache.jena.graph.Node ;
+import org.apache.jena.query.ARQ;
 import org.apache.jena.shared.PrefixMapping ;
 import org.apache.jena.shared.impl.PrefixMappingImpl ;
 import org.apache.jena.sparql.ARQConstants ;
+import org.apache.jena.sparql.function.FunctionEnv;
 import org.apache.jena.sparql.function.FunctionEnvBase ;
 import org.apache.jena.sparql.function.library.leviathan.LeviathanConstants ;
+import org.apache.jena.sparql.util.Context;
 import org.apache.jena.sparql.util.ExprUtils ;
 import org.apache.jena.sparql.util.NodeFactoryExtra ;
 
@@ -45,6 +48,14 @@ public class LibTestExpr {
     static Expr parse(String exprString) {
         return ExprUtils.parse(exprString, pmap);
     }
+    
+    /** Create an execution environment suitable for testing functions and 
expressions */ 
+    public static FunctionEnv createTest()
+    {
+        Context cxt = ARQ.getContext().copy();
+        cxt.set(ARQConstants.sysCurrentTime, NodeFactoryExtra.nowAsDateTime()) 
;
+        return new FunctionEnvBase(cxt) ;
+    }
         
     static NodeValue eval(String exprString) {
         Expr expr = ExprUtils.parse(exprString, pmap);
diff --git 
a/jena-arq/src/test/java/org/apache/jena/sparql/expr/TestExpressions2.java 
b/jena-arq/src/test/java/org/apache/jena/sparql/expr/TestExpressions2.java
index 9f08dd6..62193b8 100644
--- a/jena-arq/src/test/java/org/apache/jena/sparql/expr/TestExpressions2.java
+++ b/jena-arq/src/test/java/org/apache/jena/sparql/expr/TestExpressions2.java
@@ -20,11 +20,7 @@ package org.apache.jena.sparql.expr;
 
 import org.apache.jena.atlas.junit.BaseTest ;
 import org.apache.jena.query.QueryParseException ;
-import org.apache.jena.sparql.expr.Expr ;
-import org.apache.jena.sparql.expr.ExprEvalException ;
-import org.apache.jena.sparql.expr.NodeValue ;
 import org.apache.jena.sparql.expr.nodevalue.XSDFuncOp ;
-import org.apache.jena.sparql.function.FunctionEnvBase ;
 import org.apache.jena.sparql.util.ExprUtils ;
 import org.junit.Test ;
 
@@ -152,7 +148,7 @@ public class TestExpressions2 extends BaseTest
     /*package*/ static void eval(String string, boolean result)
     {
         Expr expr = ExprUtils.parse(string) ;
-        NodeValue nv = expr.eval(null, FunctionEnvBase.createTest()) ;
+        NodeValue nv = expr.eval(null, LibTestExpr.createTest()) ;
         boolean b = XSDFuncOp.booleanEffectiveValue(nv) ;
         assertEquals(string, result, b) ;
     }
diff --git 
a/jena-arq/src/test/java/org/apache/jena/sparql/expr/TestExpressions3.java 
b/jena-arq/src/test/java/org/apache/jena/sparql/expr/TestExpressions3.java
index 4a33e6e..464f372 100644
--- a/jena-arq/src/test/java/org/apache/jena/sparql/expr/TestExpressions3.java
+++ b/jena-arq/src/test/java/org/apache/jena/sparql/expr/TestExpressions3.java
@@ -21,7 +21,6 @@ package org.apache.jena.sparql.expr;
 import org.apache.jena.atlas.junit.BaseTest ;
 import org.apache.jena.sparql.engine.binding.Binding ;
 import org.apache.jena.sparql.expr.nodevalue.XSDFuncOp ;
-import org.apache.jena.sparql.function.FunctionEnvBase ;
 import org.apache.jena.sparql.sse.Item ;
 import org.apache.jena.sparql.sse.SSE ;
 import org.apache.jena.sparql.sse.builders.BuilderBinding ;
@@ -50,7 +49,7 @@ public class TestExpressions3 extends BaseTest
     private static void eval(String string, String bindingStr, boolean 
expected) {
         Binding binding = binding(bindingStr) ; 
         Expr expr = ExprUtils.parse(string) ;
-        NodeValue nv = expr.eval(binding, FunctionEnvBase.createTest()) ;
+        NodeValue nv = expr.eval(binding, LibTestExpr.createTest()) ;
         boolean b = XSDFuncOp.booleanEffectiveValue(nv) ;
         assertEquals(string, expected, b) ;
     }
@@ -59,7 +58,7 @@ public class TestExpressions3 extends BaseTest
     private static void evalExpr(String exprString, String bindingStr, boolean 
expected) {
         Binding binding = binding(bindingStr) ;
         Expr expr = SSE.parseExpr(exprString) ;
-        NodeValue nv = expr.eval(binding, FunctionEnvBase.createTest()) ;
+        NodeValue nv = expr.eval(binding, LibTestExpr.createTest()) ;
         boolean b = XSDFuncOp.booleanEffectiveValue(nv) ;
         assertEquals(exprString, expected, b) ;
     }
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 e8ef732..d20f070 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
@@ -27,12 +27,12 @@ import java.text.ParseException ;
 import java.text.SimpleDateFormat ;
 import java.util.Date ;
 import java.util.TimeZone ;
+import java.util.function.Predicate;
 
 import org.apache.jena.datatypes.xsd.XSDDatatype ;
 import org.apache.jena.graph.Node ;
 import org.apache.jena.graph.NodeFactory ;
 import org.apache.jena.sparql.ARQConstants ;
-import org.apache.jena.sparql.function.FunctionEnvBase ;
 import org.apache.jena.sparql.util.ExprUtils ;
 import org.junit.Assert ;
 import org.junit.Test ;
@@ -104,7 +104,7 @@ public class TestFunctions
     private static void test_exprSprintf_tz_exact(String nodeStr) {
         String exprStr = "afn:sprintf('%1$tm %1$te,%1$tY', 
"+NodeValue.makeDateTime(nodeStr).toString()+")" ;
         Expr expr = ExprUtils.parse(exprStr) ;
-        NodeValue r = expr.eval(null, FunctionEnvBase.createTest()) ;
+        NodeValue r = expr.eval(null, LibTestExpr.createTest()) ;
         assertTrue(r.isString()) ;
         String s = r.getString() ;
         // Parse the date
@@ -126,7 +126,7 @@ public class TestFunctions
     private static void test_exprSprintf_tz_possibilites(String nodeStr, 
String... possible) {
         String exprStr = "afn:sprintf('%1$tm %1$te,%1$tY', 
"+NodeValue.makeDateTime(nodeStr).toString()+")" ;
         Expr expr = ExprUtils.parse(exprStr) ;
-        NodeValue r = expr.eval(null, FunctionEnvBase.createTest()) ;
+        NodeValue r = expr.eval(null, LibTestExpr.createTest()) ;
         assertTrue(r.isString()) ;
         String s = r.getString() ;
         // Timezones! The locale data can be -1, 0, +1 from the Z day.
@@ -394,17 +394,17 @@ public class TestFunctions
                 
"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_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_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_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_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_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 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 exprAdjustDateToTz_01(){
         testEqual(
@@ -418,13 +418,13 @@ public class TestFunctions
                 
"fn:adjust-date-to-timezone('2002-03-07-07:00'^^xsd:date,'"+getDynamicDurationString()+"'^^xsd:dayTimeDuration)");
     }
 
-    @Test public void 
exprAdjustDateToTz_03(){test("fn:adjust-date-to-timezone('2002-03-07'^^xsd:date,'-PT10H'^^xsd:dayTimeDuration)",NodeValue.makeDate("2002-03-07-10:00"));}
+    @Test public void exprAdjustDateToTz_03() { 
test("fn:adjust-date-to-timezone('2002-03-07'^^xsd:date,'-PT10H'^^xsd:dayTimeDuration)",NodeValue.makeDate("2002-03-07-10:00"));}
 
-    @Test public void 
exprAdjustDateToTz_04(){test("fn:adjust-date-to-timezone('2002-03-07-07:00'^^xsd:date,'-PT10H'^^xsd:dayTimeDuration)",NodeValue.makeDate("2002-03-06-10:00"));}
+    @Test public void exprAdjustDateToTz_04() { 
test("fn:adjust-date-to-timezone('2002-03-07-07:00'^^xsd:date,'-PT10H'^^xsd:dayTimeDuration)",NodeValue.makeDate("2002-03-06-10:00"));}
 
-    @Test public void 
exprAdjustDateToTz_05(){test("fn:adjust-date-to-timezone('2002-03-07'^^xsd:date,'')",NodeValue.makeDate("2002-03-07"));}
+    @Test public void exprAdjustDateToTz_05() { 
test("fn:adjust-date-to-timezone('2002-03-07'^^xsd:date,'')",NodeValue.makeDate("2002-03-07"));}
 
-    @Test public void 
exprAdjustDateToTz_06(){test("fn:adjust-date-to-timezone('2002-03-07-07:00'^^xsd:date,'')",NodeValue.makeDate("2002-03-07"));}
+    @Test public void exprAdjustDateToTz_06() { 
test("fn:adjust-date-to-timezone('2002-03-07-07:00'^^xsd:date,'')",NodeValue.makeDate("2002-03-07"));}
 
     @Test public void exprAdjustTimeToTz_01(){
         testEqual(
@@ -438,23 +438,33 @@ public class TestFunctions
                 
"fn:adjust-time-to-timezone('10:00:00-07:00'^^xsd:time,'"+getDynamicDurationString()+"'^^xsd:dayTimeDuration)");
     }
 
-    @Test public void 
exprAdjustTimeToTz_03(){test("fn:adjust-time-to-timezone('10:00:00'^^xsd:time,'-PT10H'^^xsd:dayTimeDuration)",NodeValue.makeNode("10:00:00-10:00",XSDDatatype.XSDtime));}
+    @Test public void exprAdjustTimeToTz_03() { 
test("fn:adjust-time-to-timezone('10:00:00'^^xsd:time,'-PT10H'^^xsd:dayTimeDuration)",NodeValue.makeNode("10:00:00-10:00",XSDDatatype.XSDtime));}
 
-    @Test public void 
exprAdjustTimeToTz_04(){test("fn:adjust-time-to-timezone('10:00:00-07:00'^^xsd:time,'-PT10H'^^xsd:dayTimeDuration)",NodeValue.makeNode("07:00:00-10:00",XSDDatatype.XSDtime));}
+    @Test public void exprAdjustTimeToTz_04() { 
test("fn:adjust-time-to-timezone('10:00:00-07:00'^^xsd:time,'-PT10H'^^xsd:dayTimeDuration)",NodeValue.makeNode("07:00:00-10:00",XSDDatatype.XSDtime));}
 
-    @Test public void 
exprAdjustTimeToTz_05(){test("fn:adjust-time-to-timezone('10:00:00'^^xsd:time,'')",NodeValue.makeNode("10:00:00",XSDDatatype.XSDtime));}
+    @Test public void exprAdjustTimeToTz_05() { 
test("fn:adjust-time-to-timezone('10:00:00'^^xsd:time,'')",NodeValue.makeNode("10:00:00",XSDDatatype.XSDtime));}
 
-    @Test public void 
exprAdjustTimeToTz_06(){test("fn:adjust-time-to-timezone('10:00:00-07:00'^^xsd:time,'')",NodeValue.makeNode("10:00:00",XSDDatatype.XSDtime));}
+    @Test public void exprAdjustTimeToTz_06() { 
test("fn:adjust-time-to-timezone('10:00:00-07:00'^^xsd:time,'')",NodeValue.makeNode("10:00:00",XSDDatatype.XSDtime));}
 
-    @Test public void 
exprAdjustTimeToTz_07(){test("fn:adjust-time-to-timezone('10:00:00-07:00'^^xsd:time,'PT10H'^^xsd:dayTimeDuration)",NodeValue.makeNode("03:00:00+10:00",XSDDatatype.XSDtime));}
+    @Test public void exprAdjustTimeToTz_07() { 
test("fn:adjust-time-to-timezone('10:00:00-07:00'^^xsd:time,'PT10H'^^xsd:dayTimeDuration)",NodeValue.makeNode("03:00:00+10:00",XSDDatatype.XSDtime));}
     //@Test public void exprStrJoin()      { test("fn:string-join('a', 'b')", 
NodeValue.makeString("ab")) ; }
     
+    @Test public void localTimezone_1() { test("fn:implicit-timezone()", 
nv->nv.isDayTimeDuration()); }
+    
+    // Better name!
+    @Test public void localTimezone_2() { test("afn:timezone()", 
nv->nv.isDayTimeDuration()); }
+    
+    @Test public void localDateTime_1() { test("afn:nowtz()", nv-> 
nv.isDateTime()); }
+    // Test field defined.
+    @Test public void localDateTime_2() { test("afn:nowtz()", nv-> 
nv.getDateTime().getTimezone() > -1 ); }
+
+    @Test public void localDateTime_3() { test("afn:nowtz() = NOW()", 
NodeValue.TRUE); }
+    
     private static void testNumberFormat(String expression, String expected) {
         Expr expr = ExprUtils.parse(expression) ;
-        NodeValue r = expr.eval(null, FunctionEnvBase.createTest()) ;
+        NodeValue r = expr.eval(null, LibTestExpr.createTest()) ;
         Assert.assertTrue(r.isString());
         Assert.assertEquals(expected, r.getString()) ;
-        
     }
     
     @Test public void formatNumber_01()     { 
testNumberFormat("fn:format-number(0,'#')", "0") ; }
@@ -542,20 +552,26 @@ public class TestFunctions
 
     private void test(String exprStr, NodeValue result) {
         Expr expr = ExprUtils.parse(exprStr) ;
-        NodeValue r = expr.eval(null, FunctionEnvBase.createTest()) ;
+        NodeValue r = expr.eval(null, LibTestExpr.createTest()) ;
         assertEquals(result, r) ;
     }
     
+    private void test(String exprStr, Predicate<NodeValue> test) {
+        Expr expr = ExprUtils.parse(exprStr) ;
+        NodeValue r = expr.eval(null, LibTestExpr.createTest()) ;
+        assertTrue(exprStr, test.test(r));
+    }
+
     private void testEqual(String exprStr, String exprStrExpected) {
         Expr expr = ExprUtils.parse(exprStrExpected) ;
-        NodeValue rExpected = expr.eval(null, FunctionEnvBase.createTest()) ;
+        NodeValue rExpected = expr.eval(null, LibTestExpr.createTest()) ;
         test(exprStr, rExpected) ;
     }
     
     private void testEvalException(String exprStr) {
         Expr expr = ExprUtils.parse(exprStr) ;
         try {
-            NodeValue r = expr.eval(null, FunctionEnvBase.createTest()) ;
+            NodeValue r = expr.eval(null, LibTestExpr.createTest()) ;
             fail("No exception raised") ;
         }
         catch (ExprEvalException ex) {}
diff --git 
a/jena-arq/src/test/java/org/apache/jena/sparql/function/user/TestFunctionExpansion.java
 
b/jena-arq/src/test/java/org/apache/jena/sparql/function/user/TestFunctionExpansion.java
index 753514b..da42118 100644
--- 
a/jena-arq/src/test/java/org/apache/jena/sparql/function/user/TestFunctionExpansion.java
+++ 
b/jena-arq/src/test/java/org/apache/jena/sparql/function/user/TestFunctionExpansion.java
@@ -27,10 +27,6 @@ import org.apache.jena.sparql.expr.* ;
 import org.apache.jena.sparql.expr.nodevalue.NodeValueBoolean ;
 import org.apache.jena.sparql.expr.nodevalue.NodeValueDouble ;
 import org.apache.jena.sparql.expr.nodevalue.NodeValueInteger ;
-import org.apache.jena.sparql.function.FunctionEnvBase ;
-import org.apache.jena.sparql.function.user.UserDefinedFunction ;
-import org.apache.jena.sparql.function.user.UserDefinedFunctionDefinition ;
-import org.apache.jena.sparql.function.user.UserDefinedFunctionFactory ;
 import org.apache.jena.sparql.sse.builders.ExprBuildException ;
 import org.apache.jena.sparql.util.NodeFactoryExtra ;
 import org.junit.AfterClass;
@@ -333,7 +329,7 @@ public class TestFunctionExpansion {
         f.build("http://example/cube";, new ExprList(new NodeValueInteger(2)));
         
         Expr actual = f.getActualExpr();
-        NodeValue result = actual.eval(BindingFactory.create(), 
FunctionEnvBase.createTest());
+        NodeValue result = actual.eval(BindingFactory.create(), 
LibTestExpr.createTest());
         Assert.assertEquals(8, NodeFactoryExtra.nodeToInt(result.asNode()));
         
         //Change the definition of the function we depend on
@@ -344,7 +340,7 @@ public class TestFunctionExpansion {
         f.build("http://example/cube";, new ExprList(new NodeValueInteger(2)));
         
         actual = f.getActualExpr();
-        result = actual.eval(BindingFactory.create(), 
FunctionEnvBase.createTest());
+        result = actual.eval(BindingFactory.create(), 
LibTestExpr.createTest());
         Assert.assertEquals(8, NodeFactoryExtra.nodeToInt(result.asNode()));
     }
     
diff --git 
a/jena-arq/src/test/java/org/apache/jena/sparql/function/user/TestFunctionNonExpansion.java
 
b/jena-arq/src/test/java/org/apache/jena/sparql/function/user/TestFunctionNonExpansion.java
index 4fb70bd..b5b4ef8 100644
--- 
a/jena-arq/src/test/java/org/apache/jena/sparql/function/user/TestFunctionNonExpansion.java
+++ 
b/jena-arq/src/test/java/org/apache/jena/sparql/function/user/TestFunctionNonExpansion.java
@@ -23,10 +23,6 @@ import java.util.ArrayList ;
 import org.apache.jena.sparql.engine.binding.BindingFactory ;
 import org.apache.jena.sparql.expr.* ;
 import org.apache.jena.sparql.expr.nodevalue.NodeValueInteger ;
-import org.apache.jena.sparql.function.FunctionEnvBase ;
-import org.apache.jena.sparql.function.user.UserDefinedFunction ;
-import org.apache.jena.sparql.function.user.UserDefinedFunctionDefinition ;
-import org.apache.jena.sparql.function.user.UserDefinedFunctionFactory ;
 import org.apache.jena.sparql.util.NodeFactoryExtra ;
 import org.junit.AfterClass ;
 import org.junit.Assert ;
@@ -85,7 +81,7 @@ public class TestFunctionNonExpansion {
         f.build("http://example/cube";, new ExprList(new NodeValueInteger(2)));
         
         Expr actual = f.getActualExpr();
-        NodeValue result = actual.eval(BindingFactory.create(), 
FunctionEnvBase.createTest());
+        NodeValue result = actual.eval(BindingFactory.create(), 
LibTestExpr.createTest());
         Assert.assertEquals(8, NodeFactoryExtra.nodeToInt(result.asNode()));
         
         //Change the definition of the function we depend on
@@ -94,7 +90,7 @@ public class TestFunctionNonExpansion {
         f.build("http://example/cube";, new ExprList(new NodeValueInteger(2)));
         
         actual = f.getActualExpr();
-        result = actual.eval(BindingFactory.create(), 
FunctionEnvBase.createTest());
+        result = actual.eval(BindingFactory.create(), 
LibTestExpr.createTest());
         Assert.assertEquals(4, NodeFactoryExtra.nodeToInt(result.asNode()));
     }
 }

Reply via email to