/// <summary>
        /// Gets the numeric value of the function in the given Evaluation Context for the given Binding ID
        /// </summary>
        /// <param name="context">Evaluation Context</param>
        /// <param name="bindingID">Binding ID</param>
        /// <returns></returns>
        public override IValuedNode Evaluate(SparqlEvaluationContext context, int bindingID)
        {
            IValuedNode temp = _expr.Evaluate(context, bindingID);

            if (temp != null)
            {
                return(ValueInternal(temp.AsDateTimeOffset()));
            }
            else
            {
                throw new RdfQueryException("Unable to evaluate an XPath Date Time function on a null argument");
            }
        }
        /// <summary>
        /// Calculates the value of the function in the given Evaluation Context for the given Binding ID.
        /// </summary>
        /// <param name="context">Evaluation Context.</param>
        /// <param name="bindingID">Binding ID.</param>
        /// <returns></returns>
        public virtual IValuedNode Evaluate(SparqlEvaluationContext context, int bindingID)
        {
            IValuedNode temp = _expr.Evaluate(context, bindingID);

            if (temp != null)
            {
                DateTimeOffset dt = temp.AsDateTimeOffset();
                // Regex based check to see if the value has a Timezone component
                // If not then the result is a null
                if (!Regex.IsMatch(temp.AsString(), "(Z|[+-]\\d{2}:\\d{2})$"))
                {
                    return(null);
                }

                // Now we have a DateTime we can try and return the Timezone
                if (dt.Offset.Equals(TimeSpan.Zero))
                {
                    // If Zero it was specified as Z (which means UTC so zero offset)
                    return(new StringNode(null, "PT0S", UriFactory.Create(XmlSpecsHelper.XmlSchemaDataTypeDayTimeDuration)));
                }
                else
                {
                    // If the Offset is outside the range -14 to 14 this is considered invalid
                    if (dt.Offset.Hours < -14 || dt.Offset.Hours > 14)
                    {
                        return(null);
                    }

                    // Otherwise it has an offset which is a given number of hours and minutse
                    string offset = "PT" + Math.Abs(dt.Offset.Hours) + "H";
                    if (dt.Offset.Hours < 0)
                    {
                        offset = "-" + offset;
                    }
                    if (dt.Offset.Minutes != 0)
                    {
                        offset = offset + Math.Abs(dt.Offset.Minutes) + "M";
                    }
                    if (dt.Offset.Hours == 0 && dt.Offset.Minutes < 0)
                    {
                        offset = "-" + offset;
                    }

                    return(new StringNode(null, offset, UriFactory.Create(XmlSpecsHelper.XmlSchemaDataTypeDayTimeDuration)));
                }
            }
            else
            {
                throw new RdfQueryException("Unable to evaluate an XPath Date Time function on a null argument");
            }
        }
        /// <summary>
        /// Gets the date based on the stored value using the default value if there was no stored value
        /// </summary>
        /// <param name="t">Triple whose object is the stored value</param>
        /// <param name="defaultValue">Default value</param>
        /// <returns>Date</returns>
        private static DateTimeOffset?GetDate(Triple t, DateTimeOffset?defaultValue)
        {
            if (t == null)
            {
                return(defaultValue);
            }
            INode n = t.Object;

            if (n.NodeType == NodeType.Literal)
            {
                IValuedNode value = n.AsValuedNode();
                try
                {
                    return(value.AsDateTimeOffset());
                }
                catch (RdfQueryException)
                {
                    return(defaultValue);
                }
            }
            return(defaultValue);
        }
        /// <summary>
        /// Gets the Timezone of the Argument Expression as evaluated for the given Binding in the given Context
        /// </summary>
        /// <param name="context">Evaluation Context</param>
        /// <param name="bindingID">Binding ID</param>
        /// <returns></returns>
        public override IValuedNode Evaluate(SparqlEvaluationContext context, int bindingID)
        {
            IValuedNode temp = _expr.Evaluate(context, bindingID);

            if (temp != null)
            {
                DateTimeOffset dt = temp.AsDateTimeOffset();
                // Regex based check to see if the value has a Timezone component
                // If not then the result is a null
                if (!Regex.IsMatch(temp.AsString(), "(Z|[+-]\\d{2}:\\d{2})$"))
                {
                    return(new StringNode(null, string.Empty));
                }

                // Now we have a DateTime we can try and return the Timezone
                if (dt.Offset.Equals(TimeSpan.Zero))
                {
                    // If Zero it was specified as Z (which means UTC so zero offset)
                    return(new StringNode(null, "Z"));
                }
                else
                {
                    // If the Offset is outside the range -14 to 14 this is considered invalid
                    if (dt.Offset.Hours < -14 || dt.Offset.Hours > 14)
                    {
                        return(null);
                    }

                    // Otherwise it has an offset which is a given number of hours (and minutes)
                    return(new StringNode(null, dt.Offset.Hours.ToString("00") + ":" + dt.Offset.Minutes.ToString("00")));
                }
            }
            else
            {
                throw new RdfQueryException("Unable to evaluate a Date Time function on a null argument");
            }
        }