Bạn mong đợi 1-01-01 ... 1-12-31
... nhưng làm thế nào PostgreSQL phải biết ý bạn là gì?
Các ký tự của chuỗi đầu vào được diễn giải theo cài đặt của phiên hiện tại của bạn (cài đặt mặc định là cài đặt chung trong postgressql.conf
trừ khi bị xử lý quá mức). Cụ thể là datestyle
:
DateStyle
(string
)Đặt định dạng hiển thị cho các giá trị ngày và giờ, cũng như các quy tắc để diễn giải các giá trị nhập ngày không rõ ràng. Vì lý do lịch sử, biến này chứa hai thành phần độc lập:định dạng đầu ra (
ISO
,Postgres
,SQL
, hoặcGerman
) và thông số đầu vào / đầu ra cho đặt hàng năm / tháng / ngày (DMY
,MDY
hoặcYMD
). Chúng có thể được đặt riêng biệt hoặc cùng nhau. Các từ khóaEuro
vàEuropean
là từ đồng nghĩa củaDMY
; các từ khóaUS
,NonEuro
vàNonEuropean
là từ đồng nghĩa củaMDY
. Xem Phần 8.5 để biết thêm thông tin. Mặc định tích hợp sẵn làISO, MDY
, nhưng initdb sẽ khởi tạo tệp cấu hình với cài đặt tương ứng với hành vi củalc_time
đã chọn ngôn ngữ.
(Trong khi định dạng đầu ra chủ yếu được xác định bởi lc_time
.)
Trong trường hợp của bạn, dấu thời gian bị cắt xén theo nghĩa đen 1-12-31 23:59:59
rõ ràng được hiểu là:
D-MM-YY h24:mi:ss
Mặc dù bạn đã hy vọng:
Y-MM-DD h24:mi:ss
3 tùy chọn
-
Đặt
datestyle
để nó diễn giải các nghĩa đen giống như cách bạn làm. Có thểISO, YMD
? -
Sử dụng
to_timestamp()
để diễn giải chuỗi ký tự theo cách được xác định rõ ràng - độc lập với các cài đặt khác. Tốt hơn nhiều.SELECT to_timestamp('1-12-31 23:59:59', 'Y-MM-DD h24:mi:ss');
-
Tốt hơn, hãy sử dụng định dạng ISO 8601 (
YYYY-MM-DD
) cho tất cả các ký tự ngày giờ. Điều đó rõ ràng và độc lập với bất kỳ cài đặt nào .SELECT '2001-12-31 23:59:59'::timestamp;
Viết lại truy vấn
Truy vấn của bạn bị lỗi để bắt đầu. Xử lý các truy vấn phạm vi khác nhau. Như:
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;
Hoặc đơn giản hơn:
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;
Các loại phạm vi trong PostgreSQL 9.2 hoặc mới hơn có thể được quan tâm.