timestampandtz

This Release
timestampandtz 1.0.2
Date
Status
Stable
Other Releases
Abstract
Timestamp and timezone data type for PostgreSQL
Description
timestampandtz is a data type for PostgreSQL that stores the timestamp and the source timezone
Released By
mweber26
License
PostgreSQL
Resources
Special Files
Tags

Extensions

timestampandtz 1.0.2
Timestamp and timezone data type for PostgreSQL

README

timestampandtz

A postgresql date/time type that stores both the timestamp and the timezone.

Input/Output

The type supports both input and output from text format both with a specified timezone and with the implicit session/database time zone. The standard timestamp date parsing is supported with the implicit session timezone:

```sql postgres=# select '9/1/2014 10:15pm'::timestampandtz;

timestampandtz

2014-09-01 22:15:00 @ US/Eastern (1 row) ```

The format for the input/output of direct timestampandtz is [date string] @ [timezone]. Using this format, the type also supports a forced timezone (doesn't matter what the session time zone is set to):

```sql postgres=# select '9/1/2014 10:15pm @ US/Pacific'::timestampandtz;

timestampandtz

2014-09-01 22:15:00 @ US/Pacific (1 row) ```

You can see that the output is always the local time with the timezone displayed.

Binary format

The internal binary format of timestampandtz is 10 bytes with the standard 8-byte timestamp (in UTC) combines with a 2-byte timezone ID. The timezone IDs are fixed, and are simply a list of timezones from pg_timezone_names with each timezone assigned a specific fixed ID.

Casts

The type supports casting from both timestamp and timestamptz and to both timestamp and timestamptz.

Cast to timestamp

Casts to timestamp are always done from the local timestamp of the timestampandtz. Since the "at time zone" clause is also supported, the default, un-adorned conversion is to UTC:

```sql postgres=# select '9/1/2014 10:15pm @ US/Eastern'::timestampandtz::timestamp;

timestamp

2014-09-01 22:15:00 (1 row)

postgres=# select '9/1/2014 10:15pm @ US/Eastern'::timestampandtz at time zone 'utc';

timestamp

2014-09-02 02:15:00 (1 row) ```

Cast to timestamptz

Casts to timestamptz follow the same rules as normal timestamptz. We convert our local timestamp to the UTC and the display routine for timestamptz takes over converting it to the local session timezone:

```sql postgres=# set time zone 'US/Eastern'; SET postgres=# select '9/1/2014 10:15pm @ US/Eastern'::timestampandtz::timestamptz;

timestamptz

2014-09-01 22:15:00-04 (1 row) ```

Cast from timestamp

Casts from timestamp are takes as a local timestamp converted to the session time zone:

```sql postgres=# select '9/1/2014 10:15pm'::timestamp::timestampandtz;

timestampandtz

2014-09-01 22:15:00 @ US/Eastern (1 row) ```

Cast from timestamptz

Casts from timestamp are takes as a local timestamp converted to the session time zone:

```sql postgres=# select '9/1/2014 10:15pm'::timestamptz::timestampandtz;

timestampandtz

2014-09-01 22:15:00 @ US/Eastern (1 row) ```

Compares

All comparison operations are complete and act as point-in-time comparisons, so they are immutable (unlike timestamptz which relys on the current sesssion time zone):

```sql postgres=# select '9/1/2014 10:15pm @ US/Eastern'::timestampandtz='9/1/2014 7:15pm @ US/Pacific'::timestampandtz;

?column?

t (1 row) ```

Using the standard set of casts support for now()/current_timestamp is preserved when using timestampandtz:

```sql postgres=# create table times (dt timestampandtz); CREATE TABLE postgres=# insert into times values (now()); INSERT 0 1 postgres=# insert into times values (current_timestamp); INSERT 0 1 postgres=# select * from times;

dt

2014-09-13 23:26:17.170931 @ US/Eastern 2014-09-13 23:26:21.146286 @ US/Eastern (2 rows) ```

Indexing

Because we have the time zone stored with the point-in-time timestamp, full btree indexing is supported (where the comparisons occur in UTC time, but values are preserved in local time zones).

```sql postgres=# create table times (dt timestampandtz); CREATE TABLE postgres=# create index ix_times_dt on times(dt); CREATE INDEX postgres=# insert into times values ('9/1/2014 10:15pm @ US/Eastern'::timestampandtz); INSERT 0 1 postgres=# insert into times values ('9/1/2014 9:16pm @ US/Central'::timestampandtz); INSERT 0 1 postgres=# insert into times values ('9/1/2014 10:17pm'::timestampandtz); INSERT 0 1 postgres=# insert into times values ('9/1/2014 7:18pm @ US/Pacific'::timestampandtz); INSERT 0 1 postgres=# select * from times order by dt;

dt

2014-09-01 22:15:00 @ US/Eastern 2014-09-01 21:16:00 @ US/Central 2014-09-01 22:17:00 @ US/Eastern 2014-09-01 19:18:00 @ US/Pacific (4 rows) postgres=# select * from times where dt >= '2014-09-02 02:17:00 @ UTC' order by dt;

dt

2014-09-01 22:17:00 @ US/Eastern 2014-09-01 19:18:00 @ US/Pacific (2 rows) ```

Intervals

Intervals are supported and work based on wall clocks with respect to daylight savings time. For example, at the crossover (+3 months) of DST in the US/Eastern, the wall clock stays the same (8:15pm + 3 months is still 8:15pm) and the time zone remains the same. The thing that changes is the internal UTC timestamp (since we crossed DST):

```sql postgres=# select ('9-18-2014 8:15pm @ US/Eastern'::timestampandtz)::timestamp;

timestamp

2014-09-19 00:15:00 (1 row)

postgres=# select '9-18-2014 8:15pm @ US/Eastern'::timestampandtz + interval '3 months';

?column?

2014-12-18 20:15:00 @ US/Eastern (1 row)

postgres=# select ('9-18-2014 8:15pm @ US/Eastern'::timestampandtz + interval '3 months')::timestamp;

timestamp

2014-12-19 01:15:00 (1 row) ```

Functions

tzmove

This function allows you to move the timezone for a timestampandtz value:

```sql postgres=# select tzmove('9-18-2014 8:15pm @ US/Eastern'::timestampandtz, 'US/Pacific');

tzmove

2014-09-18 17:15:00 @ US/Pacific (1 row) ```

date_trunc and date_trunc_at

Functions to perfrom date truncation on timestampandtz values. See https://github.com/mweber26/timestampandtz/wiki/date_trunc for a detailed description.

date_part

Function to get a date part from the local time of the timestamp.

at time zone

The standard at time zone clause works by returning a standard timestamp (no zone information) at the specified time zone:

```sql postgres=# select '9-18-2014 8:15pm @ US/Eastern'::timestampandtz at time zone 'US/Pacific';

timezone

2014-09-18 17:15:00 (1 row) ```