This is probably a very simple question, but it's hard to Google because it matches too many different questions.
I want to get the timezone (or offset) of timestamps saved in my database.
For example, right now in my database I have
expired_at
---------------------
2018年04月28日 00:00:00
2018年03月28日 08:00:00
2018年02月28日 05:00:00
I want to find all expired_at
that has the PST offset.
So my pseudo-code would be something like this
SELECT expired_at FROM table WHERE expired_at IS IN TIMEZONE('PST')
Can I get some help. Thanks!
PS. Basically I am trying to fix a data integrity issue by finding all UTC timestamp and updating them to be PST. The database is screwed up right now with a mix of many different timezones.
3 Answers 3
The documentation on Postgres timestamps says:
For timestamp with time zone, the internally stored value is always in UTC (Universal Coordinated Time, traditionally known as Greenwich Mean Time, GMT). An input value that has an explicit time zone specified is converted to UTC using the appropriate offset for that time zone. If no time zone is stated in the input string, then it is assumed to be in the time zone indicated by the system's TimeZone parameter, and is converted to UTC using the offset for the timezone zone.
Contrary to what a reasonable person might expect when reading timestamp with time zone
, this Postgres datatype doesn't actually store a timezone. Internally, the value is always converted to UTC.
The information about the input timezone is lost when saving the value to the database. As far as I know, there is no way to get the information you seek.
-
Yea you're right. I am an idiot. That's the hours, not the timezone. Thanks!vinhboy– vinhboy2017年02月13日 19:57:12 +00:00Commented Feb 13, 2017 at 19:57
The data you want does not exist. Timestamps do not contain time zone data. Timestamps are always stored in UTC. The time zone information is used to convert to UTC on the way into the database, and to format UTC into some other format on the way out. It is not stored, unless you create an additional column to store it in.
It, probably, depends on the version of your SQL and how table was formatted. Accordingly to https://www.postgresql.org/docs/current/functions-datetime.html you can extract the timezone using the keyword
SELECT EXTRACT(timezone_hour FROM your_timestamp_column)
that gives "The hour component of the time zone offset" (also you may consider "timezone" and "timezone_minute"). There is also option to extract timezone_minute for the half-hour zones
-
there is no function
timezone_hour()
in Postgres. And as Postgres doesn't actually store the timezone, there is no way to retrieve that informationuser1822– user18222020年01月10日 06:57:48 +00:00Commented Jan 10, 2020 at 6:57 -
1@DanyloZherebetskyy: dbfiddle.uk/…user1822– user18222020年10月09日 20:20:34 +00:00Commented Oct 9, 2020 at 20:20
-
1@DanyloZherebetskyy sucks for the ~1.5 billion people living in a half-hour time zone then.OrangeDog– OrangeDog2020年10月10日 12:08:47 +00:00Commented Oct 10, 2020 at 12:08
-
1As Postgres does not store a time zone value in a
timestamp with time zone
that only retrieves the time zone hours from the current session time zone: dbfiddle.uk/… It's essentially the same asshow timezone;
user1822– user18222020年10月16日 05:41:56 +00:00Commented Oct 16, 2020 at 5:41 -
1Quote from the manual "For timestamp with time zone, the internally stored value is always in UTC [...]. An input value that has an explicit time zone specified is converted to UTC using the appropriate offset for that time zone"user1822– user18222020年10月19日 19:42:06 +00:00Commented Oct 19, 2020 at 19:42
TIMESTAMP WITHOUT TIMEZONE
), but rather should be a "doesn't care" situation; this is usually done by explicitly storing everything in UTC. The reasoning has to do with the fact that an event represents an actual, distinct, specific instant in time, and isn't really bound to any calendar.US/Pacific
orAmerica/Los_Angeles
.