时间戳类型
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语句控制时区,可控性强一点。