# Functions, Operators, and Data Types

The implementation of the xs:date, xs:time, and xs:dateTime data types has been rewritten. The new implementation places much less reliance on the `Calendar` and `Date` types in the Java class library, using these only when dates and times need to be passed to or from Java application code. All calculations and comparisons are now implemented within Saxon, rather than relying on the JVM. The new implementation allows timezones up to +/- 14:00, and maintains the time to microsecond precision.

Comparison of dates with no timezone now uses the implicit timezone as defined in the current specifications.

Dividing one duration by another now returns a decimal (as required by the specification), rather than a double.

When multiplying or dividing a yearMonthDuration by a number, the result is now rounded as defined in the specification (previously it was rounded down); and an error is now reported if the number is NaN. This also affects the result of `avg()` applied to a sequence of `yearMonthDuration` values.

A cast that can never succeed (for example, casting from a boolean to a date) is now detected as a compile-time error. Previously such errors were always reported at run-time.

Saxon now reports errors when Base64 input is incorrectly formatted. Previously a base64 decoder was used that always recovered from errors. (This may cause problems since badly formatted Base64 is not uncommon. However, Saxon does what the specs say...)

The new function `escape-html-uri()` is implemented. The HTML and XHTML output methods now normalize a non-ASCII URL (into normalization form NFC) before escaping it.

The implementation of the `document-uri()` function has been changed to conform to the current specification. It now returns a URI only for documents that are present in the document pool, that is, documents that can be retrieved using the `doc()` function. Handling of non-document nodes and empty sequences also now matches the spec.

The obsolete `expanded-QName()` function has been removed. Use `QName()` instead.

The obsolete `escape-uri()` function has been dropped. Use `encode-for-uri()` or `iri-to-uri()` instead.

The details of how `encode-for-uri()` and `iri-to-uri()` handle certain characters in the input (notably "#" and "%") have been brought into line with the current specification.

The prefixes returned by `in-scope-prefixes()` are now values of type `xs:NCName`, except for the "null" prefix, which is returned as an `xs:string`.

The function `prefix-from-QName` now returns an empty sequence in the case of a QName with no prefix. Previously it returned an invalid zero-length `xs:NCName`.

The keyword `void()` is no longer accepted as a synonym for `empty-sequence()`.

For functions that expect a collation as an argument, the collation must now be a valid URI. If it is a relative URI, it is resolved against the base URI before being passed to the CollationURIResolver.

The five functions contains(), substring-before(), substring-after(), starts-with(), and ends-with() now use the default collation rather than the Unicode codepoint collation if no explicit collation is specified. (Since the default for the default collation is the Unicode codepoint collation, this is unlikely to make much difference). This change was agreed to the spec some while back but its implementation in Saxon was overlooked.

To improve the way that doc-available() works with a user-written URIResolver, it is now possible for a URIResolver to indicate that when it returns null, the standard URI resolver should not be invoked (as normally happens under the JAXP rules). The way to achieve this is for the URIResolver to implement the marker interface `net.sf.saxon.NonDelegatingURIResolver`.

Next