87

PostgreSQL field type for unix timestamp :

  • to store it as unix time stamp
  • to retrieve it as a unix timestamp as well.

Have been going through Date/Time Types postgreSQL V 9.1.


  • Is integer the best way to go!? (this is what I had done when I was using MySQL. Had used int(10))

3 Answers 3

151

The unix epoch timestamp right now (2014-04-09) is 1397071518. So we need an data type capable of storing a number at least this large.

What data types are available?

If you refer to the PostgreSQL documentation on numeric types you'll find the following options:

Name      Size     Minimum               Maximum
smallint  2 bytes  -32768                +32767
integer   4 bytes  -2147483648           +2147483647
bigint    8 bytes  -9223372036854775808  +9223372036854775807

What does that mean in terms of time representation?

Now, we can take those numbers and convert them into dates using an epoch converter:

Name      Size     Minimum Date      Maximum Date
smallint  2 bytes  1969-12-31        1970-01-01
integer   4 bytes  1901-12-13        2038-01-18
bigint    8 bytes  -292275055-05-16  292278994-08-17

Note that in the last instance, using seconds puts you so far into the past and the future that it probably doesn't matter. The result I've given is for if you represent the unix epoch in milliseconds.

So, what have we learned?

  1. smallint is clearly a bad choice.
  2. integer is a decent choice for the moment, but your software will blow up in the year 2038. The Y2K apocalypse has nothing on the Year 2038 Problem.
  3. Using bigint is the best choice. This is future-proofed against most conceivable human needs, though the Doctor may still criticise it.

You may or may not consider whether it might not be best to store your timestamp in another format such as the ISO 8601 standard.

Sign up to request clarification or add additional context in comments.

1 Comment

very good answer and very well ilustrated the pro and cons of each data type
37

I'd just go with using TIMESTAMP WITH(OUT) TIME ZONE and use EXTRACT to get a UNIX timestamp representation when you need one.

Compare

SELECT NOW();

with

SELECT EXTRACT(EPOCH FROM NOW());

6 Comments

As I am saying, I want to store Unix timestamps. Does the timestamp datatype store the literal unix timestamp?
TIMESTAMP WITH(OUT) TIME ZONE does not store the literal timestamps.
I really don't think the downvote was called for. Postgres doesn't have a data type that literally maps to unix timestamp. You have to either use postgres timestamp or a non-temporal type. If you do the latter you won't be able to use SQL to compare timestamps
Then convert to Postgres timestamp on store and convert back (with extract like I showed you) when you fetch the data back. It's a better solution than bodging it with an int or string
By default TIMESTAMP WITH TIME ZONE is stored as a 64-bit integer of the microseconds from midnight 2000-01-01 UTC (ignoring leap seconds, so really more like UT1). That converts pretty quickly and easily to Unix time, while allowing easy presentation and date math. If you really want the coarser resolution, integer presentation, and difficulty in date calculations, feel free to use bigint or numeric. There aren't too many situations where that's a net win, but maybe you have one of those few.
|
2

integer would be good, but not enough good, because postgresql doesn't support unsigned types

5 Comments

I think I can counter that with a check to make it behave like an unsigned number.
until 2038 this is not a problem :)
probably use bigint then. But it would not be good to store the extra bits.
Maia storage really so expensive that you need to worry about a couple of bytes extra per row?
@GordonM Sorry to grave dig, but highly depends on the traffic your database receives..

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.