PostgreSQL中使用timestampz类型如何保留UTC偏移量?
首先得明确:PostgreSQL的timestamptz(带时区的时间戳)从设计上就不会保留原始输入的时区偏移——它会把任何带偏移的时间转换为UTC时间存储,所以你插入2022-10-20 00:00:00+01后,存储的就是对应的UTC时间2022-10-19 23:00:00+00,原始偏移信息确实会丢失,这是该类型的特性,没法通过配置改变。
如果不想新增列,只能换用其他字段类型来存储,以下是几种可行的方式:
用
text类型直接存储完整字符串
直接把带偏移的时间字符串存在text列里,比如插入'2022-10-20 00:00:00+01',查询时也能完整拿到原始内容。但缺点是失去了日期时间类型的原生特性,不能直接做时间加减、范围查询这类操作,需要先转换类型再处理。用
jsonb类型封装时间和偏移
把时间和偏移打包成JSON对象存在一个列里,比如插入'{"datetime": "2022-10-20 00:00:00", "offset": "+01"}'。这种方式既能保留原始偏移,也能通过JSON操作提取出时间和偏移来做后续处理,比纯text灵活一些,不过同样不如原生时间类型高效。自定义复合类型
你可以创建一个自定义的复合类型,把时间和偏移作为两个字段封装到一个类型里,比如:CREATE TYPE timetz_with_offset AS (ts timestamp, offset interval);插入数据时用
ROW('2022-10-20 00:00:00', '1 hour')::timetz_with_offset,查询时可以通过(col).ts和(col).offset分别获取时间和偏移。这种方式兼顾了类型特性和偏移保留,但需要自己维护自定义类型。
总结:timestamptz本身做不到保留原始偏移,必须换用其他类型才能在单一列里同时存储时间和原始偏移信息。
内容的提问来源于stack exchange,提问作者cglacet

