あなたは期待1-01-01 ... 1-12-31
していました...しかし、PostgreSQLはあなたがそれを意味することをどのように知っているのでしょうか?
入力文字列リテラルは、現在のセッションの設定に従って解釈されます (無視されpostgressql.conf
ない限り、既定では一般的な設定になります)。特にdatestyle
:
DateStyle
( string
)
日付と時刻の値の表示形式と、あいまいな日付入力値を解釈するためのルールを設定します。歴史的な理由から、この変数には 2 つの独立したコンポーネントが含まれています。出力形式の指定 ( ISO
、Postgres
、SQL
、またはGerman
) と、年/月/日の順序の入力/出力の指定 ( DMY
、MDY
、またはYMD
) です。これらは個別に、またはまとめて設定できます。キーワード
Euro
andは;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 以降の範囲型が興味深いかもしれません。