# 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. It can be set with the isc_dpb_session_time_zone DPB, and if not, it starts by default 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 ```