Je had verwacht 1-01-01 ... 1-12-31
... maar hoe moet PostgreSQL weten wat je daarmee bedoelt?
Letterlijke invoertekenreeksen worden geïnterpreteerd volgens de instellingen van uw huidige sessie (die standaard zijn ingesteld op algemene instellingen in postgressql.conf
tenzij overruled). In het bijzonder datestyle
:
DateStyle
(string
)Stelt het weergaveformaat in voor datum- en tijdwaarden, evenals de regels voor het interpreteren van dubbelzinnige datuminvoerwaarden. Om historische redenen bevat deze variabele twee onafhankelijke componenten:de specificatie van het uitvoerformaat (
ISO
,Postgres
,SQL
, ofGerman
) en de invoer/uitvoerspecificatie voor jaar/maand/dag-bestelling (DMY
,MDY
,ofYMD
). Deze kunnen afzonderlijk of samen worden ingesteld. De trefwoordenEuro
enEuropean
zijn synoniemen voorDMY
; de trefwoordenUS
,NonEuro
, enNonEuropean
zijn synoniemen voorMDY
. Zie Sectie 8.5 voor meer informatie. De ingebouwde standaard isISO, MDY
, maar initdb zal het configuratiebestand initialiseren met een instelling die overeenkomt met het gedrag van de gekozenlc_time
landinstelling.
(Terwijl het uitvoerformaat meestal wordt bepaald door lc_time
.)
In jouw geval is het verminkte tijdstempel letterlijk 1-12-31 23:59:59
wordt duidelijk geïnterpreteerd als:
D-MM-YY h24:mi:ss
Terwijl je had gehoopt:
Y-MM-DD h24:mi:ss
3 opties
-
Stel
datestyle
in zodat het letterlijke op dezelfde manier interpreteert als jij. MisschienISO, YMD
? -
Gebruik
to_timestamp()
om de tekenreeks letterlijk op een goed gedefinieerde manier te interpreteren - onafhankelijk van andere instellingen. Veel beter.SELECT to_timestamp('1-12-31 23:59:59', 'Y-MM-DD h24:mi:ss');
-
Beter nog, gebruik ISO 8601-formaat (
YYYY-MM-DD
) voor alle datetime-letterwoorden. Dat is ondubbelzinnig en onafhankelijk van welke instellingen dan ook .SELECT '2001-12-31 23:59:59'::timestamp;
Vraag opnieuw schrijven
Uw vraag is om te beginnen al defect. Behandel bereikquery's anders. Vind ik leuk:
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;
Of, nog eenvoudiger:
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;
Bereiktypen in PostgreSQL 9.2 of nieuwer kunnen interessant zijn.