EPUB | CHM | PDF

Datestyle and timestamp

Top Previous Next

Understanding datestyle issues

To set datestyle settings on the server we use datestyle variable.

From PostgreSQL help:

DateStyle (string): Sets the display format for date and time values, as well as the rules for interpreting ambiguous date input values. For historical reasons, this variable contains two independent components: the output format specification (ISO, Postgres, SQL, or German) and the input/output specification for year/month/day ordering (DMY, MDY, or YMD). These can be set separately or together. The keywords Euro and European are synonyms for DMY; the keywords US, NonEuro, and NonEuropean are synonyms for MDY. See Section 8.5 for more information. The built-in default is ISO, MDY, but initdb will initialize the configuration file with a setting that corresponds to the behavior of the chosen lc_time locale.

On the client side we must provide date information according to locale settings of client, or in the form of TDateField.DisplayFormat if specified so.

The goal of PostgresDAC is to handle these issues. The main idea is that dates from the server are coming in a textual form, but Delphi TDateField class expects binary TDateTime (double) representation. So to be independent of server datestyle settings PostgresDAC executes such query at the start of each session:

SET DateStyle TO 'ISO, MDY'

It affects only on local session settings and is not visible to other sessions. Now we are absolutely sure what format will be used to represent date values from server.

However, we have a negative aspect. If one decide to execute insert (update) query directly, i.e:

PSQLDatabase1.EXECSQL('INSERT ('2004-06-26 20:31:43') INTO ...')

It will get error message. For such issues we strongly recommend to change session datestyle settings temporarily:

PSQLDatabase1.ExecSQL('SET datestyle TO <....>');
try
   PSQLDatabase1.EXECSQL('INSERT ('2004-06-26 20:31:43') INTO ...')
finally
PSQLDatabase1.ExecSQL('SET datestyle TO ''''ISO, MDY');
end;

Timestamp internals

There is one more problem: PostgreSQL timestamp type allow to store values with microseconds precision (10-6 sec), but Delphi TDateTime type precision allows only milliseconds (10-3).

That's why some queries with WHERE clause using timestamps comparison operations may fail. To avoid this you should define date columns as timestamp(0), e.g.:

CREATE TABLE history
(
  his_id integer NOT NULL,
  when timestamp(0) without time zone,
...)