Difference Between Timestamp With and Without Time Zone in PostgreSQL

Shihab Sikder Mar 29, 2022
  1. Timestamp in PostgreSQL
  2. Difference Between Timestamp With and Without Time Zone in PostgreSQL
Difference Between Timestamp With and Without Time Zone in PostgreSQL

This tutorial will discuss the types of timestamps in PostgreSQL and demonstrate their differences.

Timestamp in PostgreSQL

In PostgreSQL, there are two types of timestamps.

  1. Timestamp without time zone
  2. Timestamp with time zone

The first one stores the local date. For example, suppose it is now 11.00 in a 24H system clock.

So, this will be stored as 11.00. If this is saved in the database, say in the remote database, and someone is pulling this row from the CST time zone, he will still see it as 11.00.

However, it wasn’t the actual time. The CST needed to see that time is converted to the CST time zone.

As it doesn’t store any information regarding the time zone, it can’t be determined further in different time zones.

This problem is solved in the second method. So, whenever you push a timestamp in the database, it will pull the time zone from the host system and save the time zone with the timestamp.

Suppose we are in the GMT+6 time zone. Here’s a demonstration of the timestamp.

SELECT now() as "System Time",
now()::timestamp as "postgres Time",
now() AT TIME ZONE 'GMT' as "time without zone",
now() AT TIME ZONE 'CST' as "time without zone",
now()::timestamp at TIME ZONE 'GMT' as "Timestamp GMT",
now()::timestamp at TIME ZONE 'CST' as "Timestamp CST" ;

Here, the first column contains the system time, and the second column contains the timestamp after converting the time to the timestamp without a time zone.

Output:

          System Time          |       postgres Time        |     time without zone      |     time without zone      |         Timestamp GMT         |         Timestamp CST
-------------------------------+----------------------------+----------------------------+----------------------------+-------------------------------+-------------------------------
 2022-03-15 10:19:05.432758+06 | 2022-03-15 10:19:05.432758 | 2022-03-15 04:19:05.432758 | 2022-03-14 22:19:05.432758 | 2022-03-15 16:19:05.432758+06 | 2022-03-15 22:19:05.432758+06
(1 row)

Difference Between Timestamp With and Without Time Zone in PostgreSQL

Let’s create a table and see how it stores the timestamps and how you’ll use the without time zone and with time zone in PostgreSQL.

First, connect your psql console to Postgres and then run the following SQL command to create a table like the following:

CREATE TABLE Times(
    id INT PRIMARY KEY NOT NULL,
    time_without_zone TIMESTAMP WITHOUT TIME ZONE DEFAULT now(),
    time_with_zone TIMESTAMP WITH TIME ZONE DEFAULT now()
);

Now, populate the table with some entries.

INSERT INTO Times(id) VALUES(1);
INSERT INTO Times(id) VALUES(2);
INSERT INTO Times(id) VALUES(3);
INSERT INTO Times(id) VALUES(4);
INSERT INTO Times(id) VALUES(5);
INSERT INTO Times(id) VALUES(6);
INSERT INTO Times(id) VALUES(7);

Output:

postgres=# select * from times;
 id |     time_without_zone      |        time_with_zone
----+----------------------------+-------------------------------
  1 | 2022-03-15 10:29:03.52078  | 2022-03-15 10:29:03.52078+06
  2 | 2022-03-15 10:29:03.52564  | 2022-03-15 10:29:03.52564+06
  3 | 2022-03-15 10:29:03.526723 | 2022-03-15 10:29:03.526723+06
  4 | 2022-03-15 10:29:03.527775 | 2022-03-15 10:29:03.527775+06
  5 | 2022-03-15 10:29:03.528865 | 2022-03-15 10:29:03.528865+06
  6 | 2022-03-15 10:29:03.529941 | 2022-03-15 10:29:03.529941+06
  7 | 2022-03-15 10:29:05.045774 | 2022-03-15 10:29:05.045774+06
(7 rows)

postgres=#

As you can see, the column time_with_zone stores the time with the GMT+06 time zone. The time can be converted to any other time zone as psql will know the base for the time in the column.

Here’s a sample output that shows what will happen if you try to insert a timestamp with a time zone on a column without a time zone type.

INSERT INTO Times(id,time_without_zone,time_with_zone) VALUES(9,'2022-03-15 10:29:05.045774+06','2022-03-15 10:29:05.045774+06');

Output:

postgres=# select * from times where id=9;
 id |     time_without_zone      |        time_with_zone
----+----------------------------+-------------------------------
  9 | 2022-03-15 10:29:05.045774 | 2022-03-15 10:29:05.045774+06
(1 row)

As you can see, psql just dropped the +06 in the time_without_zone column.

If you want to see all the available time zone in Postgres, you can run the following SQL command:

postgres=# SELECT name FROM pg_timezone_names;
               name
----------------------------------
 Africa/Abidjan
 Africa/Accra
 Africa/Addis_Ababa
 Africa/Algiers
 Africa/Asmara
 Africa/Asmera
 Africa/Bamako
 Africa/Bangui
 Africa/Banjul
 Africa/Bissau
 -- More --

Here, the system is running in the GMT+6 time zone. If you want to change your Postgres time zone to a different one, you can run the following command:

postgres=# SET TIMEZONE='UTC';
SET

If you see the above tables’ data, you will see that the column with time zone is successfully converted to the UTC.

postgres=# select * from times;
 id |     time_without_zone      |        time_with_zone
----+----------------------------+-------------------------------
  1 | 2022-03-15 10:29:03.52078  | 2022-03-15 04:29:03.52078+00
  2 | 2022-03-15 10:29:03.52564  | 2022-03-15 04:29:03.52564+00
  3 | 2022-03-15 10:29:03.526723 | 2022-03-15 04:29:03.526723+00
  4 | 2022-03-15 10:29:03.527775 | 2022-03-15 04:29:03.527775+00
  5 | 2022-03-15 10:29:03.528865 | 2022-03-15 04:29:03.528865+00
  6 | 2022-03-15 10:29:03.529941 | 2022-03-15 04:29:03.529941+00
  7 | 2022-03-15 10:29:05.045774 | 2022-03-15 04:29:05.045774+00
  9 | 2022-03-15 10:29:05.045774 | 2022-03-15 04:29:05.045774+00
(8 rows)

You can see that time_without_zone remains the same, but the time_with_zone is converted from GMT+06 to UTC. To know more about timestamp formats and representation, visit the official documentation.

Shihab Sikder avatar Shihab Sikder avatar

I'm Shihab Sikder, a professional Backend Developer with experience in problem-solving and content writing. Building secure, scalable, and reliable backend architecture is my motive. I'm working with two companies as a part-time backend engineer.

LinkedIn Website