为何PostgreSQL的daterange无法存储时间,结果范围异常?
问题根源
你的操作存在两个核心问题:
范围类型不匹配
daterange是仅存储日期维度的范围类型,会自动忽略输入字符串中的时间部分(09:00:00),这就是时间信息丢失的原因。如果需要保留时分秒的时间精度,应该使用tsrange(无时区时间范围)或tstzrange(带时区时间范围)类型。daterange的区间特性
PostgreSQL的daterange默认采用左闭右开([start, end))的区间规则。当你输入[2023-01-01, 2023-01-05]时,它实际表示的是从2023-01-01 00:00:00到2023-01-05 00:00:00之前的所有时间。为了直观展示这个范围,系统会将其显示为[2023-01-01,2023-01-06),这个写法等价于包含2023-01-01全天到2023-01-05全天的所有日期。
解决办法
需要保留时间信息的场景
先将booking_range字段类型修改为tsrange或tstzrange,再执行更新语句:UPDATE booking SET booking_range = '[2023-01-01 09:00:00, 2023-01-05 09:00:00]'::tsrange;此时查询结果会完整保留时间信息,区间边界也会严格匹配你输入的时间点。
仅需日期范围的场景
如果确实只需要日期维度的范围,那么你的原始写法逻辑是正确的,系统显示的[2023-01-01,2023-01-06)只是左闭右开规则的标准表示,实际已包含2023-01-01至2023-01-05的所有日期。若想明确指定区间闭合类型,可使用构造函数:UPDATE booking SET booking_range = daterange('2023-01-01', '2023-01-05', '[]');不过查询时系统仍会以
[2023-01-01,2023-01-06)的形式展示,这是daterange的固有特性。
内容的提问来源于stack exchange,提问作者newexe91

