时间戳类型
PostgreSQL 提供两种存储时间戳的数据类型: 不带时区的 TIMESTAMP 和带时区的 TIMESTAMPTZ。
TIMESTAMP 数据类型可以同时存储日期和时间,但它不存储时区。这意味着,当修改了数据库服务器所在的时区时,它里面存储的值不会改变。
TIMESTAMPTZ 数据类型在存储日期和时间的同时还能正确处理时区。PostgreSQL 使用 UTC 值来存储 TIMESTAMPTZ 数据。在向 TIMESTAMPTZ 字段插入值的时候,PostgreSQL 会自动根据数据库服务器、用户或当前连接所在的时区,将值转换成 UTC 值,并保存到表里。当从一个 TIMESTAMPTZ 字段查询数据的时候,PostgreSQL 会把存储在其中的 UTC 值转换成数据库服务器、用户或当前连接所在的时区。也就是说,TIMESTAMPTZ 并不会存储时区,它只是存了 UTC 值,然后查询的时候会和当前时区进行转换。
TIMESTAMP 和 TIMESTAMPTZ 都使用8字节存储空间。
项目中的使用
在项目中直接使用了TIMESTAMP,把存入数据库的TIMESTAMP时间戳看成一个字符串来对待。
保存时,时区完全由SQL语句控制。可以全程使用UTC时间,也就是在构建SQL语句时,转换成UTC时间 2016-06-22 11:10:25 存入数据库;在读取时,如果需要得到long时间戳,通过 extract(epoch FROM(time))让数据库转long后返回。
也可以全程使用本地时区,例如Asia/Shanghai,在构建SQL语句保存时,转换成东八区时间 2016-06-22 19:10:25 存入数据库;在读取时,如果需要得到long时间戳,通过extract(epoch FROM(time) AT TIME ZONE 'Asia/Shanghai') 让数据库自动按照传入的本地时区转换成long。如果存入的时候按照东八区,取出的时候没有用AT TIME ZONE做时区转换,那么读出来的long会多八个小时。
这种方式不需要给数据库设置时区,完全由保存和查询时的SQL语句控制时区,可控性强一点。
参考文献