PhoenixmlDb
Dates and Times
PhoeniXML DB uses UTC; the date-time forms it accepts, API key expiry, value indexes on dates, and embedded hosts
#Dates and Times
PhoeniXML DB uses UTC. A date-time without a timezone is UTC wherever the engine stores, indexes or
compares it. A value written with a timezone (Z, +02:00) keeps its instant; write an offset to
mean another zone. There is no time-zone setting.
|
gRPC server, EPS REST server |
Embedded engine |
|
|---|---|---|
|
Typed dateTime metadata, value-index keys, JSON index keys |
UTC |
UTC |
|
API key |
UTC |
not applicable |
|
Comparison in a query or stylesheet ( |
UTC |
the zone of the host process (below) |
In both servers implicit-timezone() is PT0S, and
xs:dateTime('1996-12-12T13:13:00') < xs:dateTime('1996-12-12T13:13:00-02:00') is true, whatever
the time zone of the machine.
A server process runs in UTC: it sets the TZ environment variable of its own process to UTC at
startup. Console log timestamps, when turned on without UseUtcTimestamp, are UTC. A configuration key
PhoenixmlDb:Query:ImplicitTimezone is ignored; the server starts and lists it in the
effective-configuration event (3001).
#What is read as a date-time
Typed dateTime metadata, dateTime value-index keys and API key Expires accept these forms and
nothing else:
|
Form |
Example |
Read as |
|---|---|---|
|
|
|
that day at 00:00:00 UTC |
|
|
|
UTC when no timezone is written |
|
the same with a space in place of |
|
the same |
|
RFC 1123 |
|
that instant |
The year has four digits (0001 to 9999). Seconds are required. A fraction has any number of digits and is kept to 100 nanoseconds. Leading and trailing white space is ignored.
Refused, among others: a time with no date (12:00:00), a date with no year (1/15,
January 15), a year and month (2024-01), a two-digit year (1/15/24), 01/15/2024,
2024/01/15, 2024-1-5, 2024-01-15T12:00 (no seconds), 2024-01-15T12:00:00+0100,
2024-01-15T12:00:00+01, a lower-case t or z, 2024-01-15Z, and seconds since 1970.
A refused text:
-
as typed dateTime metadata: the request is refused with the metadata validation error;
-
in a document, at a path with a dateTime value index: the document is stored and that value has no index key;
-
as an API key
Expires: startup stops, naming the entry.
An xs:date in typed metadata or at a path with a date value index is yyyy-MM-dd (white space
around it ignored); any other text is refused as metadata and has no index key. An xs:date or
xs:time value that carries a timezone is refused as typed metadata and has no index key.
#API key expiry
PhoenixmlDb:Auth:ApiKeys:<n>:Expires (gRPC server) and Auth:ApiKey:Clients:<n>:Expires (EPS REST
server):
-
Text in one of the forms above. Without a timezone it is UTC:
2027-01-31is 2027-01-31T00:00:00Z. -
Absent: the key does not expire.
-
Empty, blank or not in one of the forms: startup stops with a message naming the entry. In the EPS REST server such an entry is also never valid when a request presents its key.
-
In the options classes
ApiKeyOptions.Expires(gRPC server) andApiKeyClientConfig.Expires(EPS) the property isstring?.
#Startup log
|
Event |
Level |
Text |
|---|---|---|
|
3010 |
Information |
|
|
3011 |
Warning |
Windows only, when the machine's time zone is not UTC (below) |
For each API key with an expiry still ahead, one Information line gives the instant in UTC, the entry
and its Id, for example
PhoenixmlDb:Auth:ApiKeys:0 (Id 'svc') expires at 2026-12-31T00:00:00.0000000+00:00. (gRPC server) or
Auth:ApiKey:Clients:0 (Id 'svc') expires at 2026-12-31T00:00:00.0000000+00:00. (EPS). A key already
expired has a warning with expired at and the instant in UTC. The effective-configuration event
(3001) shows Expires as configured.
#Value indexes on dates and times
A value index of type xs:dateTime, xs:date or xs:time answers one comparison: equality between
the attribute and a string literal that is a value of the index's type, for example
/order[@at = '2024-01-15T12:00:00']. That comparison is of text: it returns the rows whose attribute
has exactly that text.
Every other comparison on those index types is answered by a scan, with the same result as on a container that has no index:
-
a comparison with a typed value:
@at = xs:dateTime('…'),<,>=; -
a comparison with a variable, of any type:
let $x := … return /order[@at = $x], an external$v; -
a range with a string:
@at >= '2024-01-15T12:00:00Z'; -
a string literal that is not a value of the index's type:
@day = '2024-01-15Z'.
For every index type, a string literal that is not a value of the index's type is answered by a scan.
An external variable that holds a CLR DateTimeOffset is compared as text by the XQuery library.
The index writer reads numbers and dates with the invariant culture. A value index must be rebuilt when it was built on a machine whose time zone was not UTC (date-time values without a timezone), or on a machine whose regional settings were not English/invariant (numbers and dates). Nothing detects such an index. The rebuild operations:
|
Host |
Operation |
|---|---|
|
EPS REST server |
|
|
gRPC server |
|
|
Embedded |
|
Typed dateTime metadata is stored as an instant. A value stored earlier keeps its instant; a rebuild does not change it.
#Embedded engine in a host that is not in UTC
The embedded engine does not change the time zone of its host process. In a host that is not in UTC,
what the engine stores and indexes is UTC, and a comparison in a query reads a date-time without a
timezone in the host's zone. With rows a 2024-01-15T12:00:00 and b 2024-01-15T12:00:00Z, in a host
in America/New_York:
|
Answer in the host |
Answer in a UTC process |
|
|---|---|---|
|
|
a |
a, b |
|
|
b |
a, b |
|
metadata query for |
a, b |
a, b |
Run the host in UTC (TZ=UTC), or write date-times with a timezone.
#Windows
On Windows a process cannot set its own time zone. A server on a Windows machine whose time zone is UTC logs event 3010. On a machine in another zone it logs warning 3011 and starts; queries and stylesheets then compare a date-time without a timezone in the machine's zone. What is stored, indexed and read from configuration is UTC on Windows as elsewhere. Set the machine's time zone to UTC.
See also: Metadata · Indexing · Server Mode · Logging and Telemetry