SELECT
m.amount
FROM
measurement m,
to_date('Dec 01 1900', 'Mon DD YYYY') AS A(d1),
to_date('Feb 28 1900', 'Mon DD YYYY') AS B(d2),
to_date('Feb 28 1901', 'Mon DD YYYY') AS C(d3)
WHERE m.taken
BETWEEN
d1 AND
CASE WHEN d2 < d1 THEN d3 ELSE d2 END
References: conditional expressions, data type formatting functions.
EDIT: Sorry, I thought you wanted a specific year:
SELECT
amount
FROM
(SELECT
M.amount, M.taken,
to_date('Dec 01 ' || extract(YEAR FROM M.taken), 'Mon DD YYYY'),
to_date('Feb 28 ' || extract(YEAR FROM M.taken), 'Mon DD YYYY')
FROM
measurement AS M
) AS A(amount, taken, d1, d2)
WHERE
(d2 >= d1 AND taken BETWEEN d1 AND d2)
OR
(d2 < d1 AND (taken <= d2 OR taken >= d1));
If the set is big, this doesn't have a lot of chances for optimization. In that case, you can have an SQL function that converts all the dates to a certain year (say taken - (extract(year from taken) - 1900) * '1 year'::interval)
and then compare with Dec 02 1900 and Feb 28 1900. That way you can index the result of this date conversion function AND you don't have to calculate two dates for each entry.
Artefacto
2010-06-01 03:48:08