From ebe39c4b6a0949b51c521d549c7c9078317d0310 Mon Sep 17 00:00:00 2001 From: Adriano dos Santos Fernandes Date: Tue, 8 May 2018 12:54:43 -0300 Subject: [PATCH] Documentation for time zone support. --- doc/sql.extensions/README.time_zone.md | 866 +++++++++++++++++++++++++ 1 file changed, 866 insertions(+) create mode 100644 doc/sql.extensions/README.time_zone.md diff --git a/doc/sql.extensions/README.time_zone.md b/doc/sql.extensions/README.time_zone.md new file mode 100644 index 0000000000..f6ec319dff --- /dev/null +++ b/doc/sql.extensions/README.time_zone.md @@ -0,0 +1,866 @@ +# Time Zone support (FB 4.0) + +Time zone support consists of `TIME WITH TIME ZONE` and `TIMESTAMP WITH TIME ZONE` data types, expressions and statements to work with time zones and conversion between data types without/with time zones. + +The first important thing to understand is that `TIME WITHOUT TIME ZONE`, `TIMESTAMP WITHOUT TIME ZONE` and `DATE` data types are defined to use the session time zone when converting from or to a `TIME WITH TIME ZONE` or `TIMESTAMP WITH TIME ZONE`. `TIME` and `TIMESTAMP` are synonymous to theirs respectively `WITHOUT TIME ZONE` data types. + +The session time zone, as the name implies, can be a different one for each database attachment. By default it starts defined to be the same time zone used by the Firebird database OS process. + +It can then be changed with `SET TIME ZONE` statement to a given time zone or reset to its original value with `SET TIME ZONE LOCAL`. + +A time zone may be a string with a time zone region (for example, `America/Sao_Paulo`) or a hours:minutes displacement (for example, `-03:00`) from GMT. + +A time/timestamp with time zone is considered equal to another time/timestamp with time zone if their conversion to UTC are equal, for example, `time '10:00 -02' = time '09:00 -03'`, since both are the same as `time '12:00 GMT'`. This is also valid in the context of `UNIQUE` constraints and for sorting purposes. + + +## Data types + +``` +TIME [ { WITH | WITHOUT } TIME ZONE ] + +TIMESTAMP [ { WITH | WITHOUT } TIME ZONE ] +``` + +### Storage + +TIME/TIMESTAMP WITH TIME ZONE has respectively the same storage of TIME/TIMESTAMP WITHOUT TIME ZONE plus 2 bytes for the time zone identifier or displacement. + +The time/timestamp parts are stored in UTC (translated from the informed time zone). + +Time zone identifiers (from regions) are put directly in the time_zone field. They start from 65535 (which is the GMT code) and are decreasing as new time zones were/are added. + +Time zone displacements (+/- HH:MM) are encoded with `(sign * (HH * 60 + MM)) + 1439`. For example, a `00:00` displacement is encoded as `(1 * (0 * 60 + 0)) + 1439 = 1439` and `-02:00` as `(-1 * (2 * 60 + 0)) + 1439 = 1319`. + +### API structs + +``` +struct ISC_TIME_TZ +{ + ISC_TIME utc_time; + ISC_USHORT time_zone; +}; + +struct ISC_TIMESTAMP_TZ +{ + ISC_TIMESTAMP utc_timestamp; + ISC_USHORT time_zone; +}; +``` + +### API functions (FirebirdInterface.idl - IUtil interface) + +``` +void decodeTimeTz( + Status status, + const ISC_TIME_TZ* timeTz, + uint* hours, + uint* minutes, + uint* seconds, + uint* fractions, + uint timeZoneBufferLength, + string timeZoneBuffer +); + +void decodeTimeStampTz( + Status status, + const ISC_TIMESTAMP_TZ* timeStampTz, + uint* year, + uint* month, + uint* day, + uint* hours, + uint* minutes, + uint* seconds, + uint* fractions, + uint timeZoneBufferLength, + string timeZoneBuffer +); + +void encodeTimeTz( + Status status, + ISC_TIME_TZ* timeTz, + uint hours, + uint minutes, + uint seconds, + uint fractions, + const string timeZone +); + +void encodeTimeStampTz( + Status status, + ISC_TIMESTAMP_TZ* timeStampTz, + uint year, + uint month, + uint day, + uint hours, + uint minutes, + uint seconds, + uint fractions, + const string timeZone +); +``` + +## Time zone string syntax + +``` +