您期望1-01-01 ... 1-12-31
...但是 PostgreSQL 应该如何知道您的意思?
输入字符串文字根据您当前会话的设置进行解释(postgressql.conf
除非被否决,否则默认为常规设置)。特别是datestyle
:
DateStyle
( string
)
设置日期和时间值的显示格式,以及解释模糊日期输入值的规则。由于历史原因,此变量包含两个独立的组件:输出格式规范(ISO
、Postgres
、SQL
或German
)和年/月/日排序的输入/输出规范(DMY
、MDY
或YMD
)。这些可以单独设置或一起设置。关键字
Euro
和European
是DMY
;的同义词 关键字US
,
NonEuro
和NonEuropean
是 的同义词MDY
。有关详细信息,请参阅第 8.5 节。内置默认值为ISO, MDY
,但 initdb 将使用与所选行为相对应的设置初始化配置文件lc_time
语言环境。
(虽然输出格式主要由lc_time
.)
在您的情况下,残缺的时间戳文字1-12-31 23:59:59
显然被解释为:
D-MM-YY h24:mi:ss
虽然您希望:
Y-MM-DD h24:mi:ss
3个选项
设置datestyle
以便它以与您相同的方式解释文字。也许ISO, YMD
?
用于to_timestamp()
以明确定义的方式解释字符串文字 - 独立于其他设置。好多了。
SELECT to_timestamp('1-12-31 23:59:59', 'Y-MM-DD h24:mi:ss');
更好的是,对所有日期时间文字使用ISO 8601 格式( YYYY-MM-DD
)。这是明确的并且独立于任何设置。
SELECT '2001-12-31 23:59:59'::timestamp;
重写查询
您的查询一开始就有问题。以不同方式处理范围查询。像:
SELECT d.given_on
FROM documents_document d
WHERE EXTRACT('month' FROM d.given_on) = 1
AND d.given_on >= '2001-01-01 0:0'
AND d.given_on < '2002-01-01 0:0'
ORDER BY d.created_on DESC;
或者,更简单:
SELECT d.given_on
FROM documents_document d
WHERE d.given_on >= '2001-01-01 0:0'
AND d.given_on < '2001-02-01 0:0'
ORDER BY d.created_on DESC;
PostgreSQL 9.2 或更新版本中的范围类型可能很有趣。