Вы можете использовать выражение CASE WHEN
, чтобы проверить, является или нет этот год високосным годом
- Этот год високосным годом результат возвратаминус 1.
- Этот год не високосный год результат возврата.
Формула для високосного года равна
(год% 4 = 0) И (год% 100 <> 0) ИЛИ (год% 400 = 0)
Добавьте эту формулу в условие CASE WHEN
, чтобы она выглядела
this.
CREATE FUNCTION f_woy(timestamp with time zone)
RETURNS int AS $$
SELECT CASE WHEN (date_part('year',$1)::int % 4 = 0) AND ((date_part('year',$1)::int % 100 <> 0) OR (date_part('year',$1)::int % 400 = 0))
THEN to_char($1, 'WW')::int -1
ELSE to_char($1, 'WW')::int
END
$$ LANGUAGE sql IMMUTABLE STRICT;
При использовании функции f_woy
неделя високосного года будет такой же, как и у недели нормального года.
SELECT f_woy(('2007-06-24 14:19:46.502-07'::timestamp at time zone 'UTC' at
time zone 'america/los_angeles')::date),
f_woy(('2008-06-24 14:19:46.502-07'::timestamp at time zone 'UTC' at
time zone 'america/los_angeles')::date)
Результат
f_woy f_woy
25 25
sqlfiddle: https://dbfiddle.uk/?rdbms=postgres_9.6&fiddle=b43eb6f9c2accde5fc74ebe980a039d7
РЕДАКТИРОВАТЬ
високосный год означает, что добавится 29 февраля в этом годуТаким образом, вы можете попробовать это, чтобы сделать это.
IsLeapYear
функция получает этот год или не является високосным годом.
create or replace function IsLeapYear(int)
returns boolean as $$
select $1 % 4 = 0 and ($1 % 100 <> 0 or $1 % 400 = 0)
$$ LANGUAGE sql IMMUTABLE STRICT;
f_woy
функция получает номер текущей недели.
create or replace function f_woy(date)
returns int language plpgsql as $$
declare
currentYear int = extract (year from $1);
LeapYearShift int = 1 + (IsLeapYear(currentYear) and $1 > make_date(currentYear, 2, 28))::int;
begin
return ((extract(doy from $1)::int)- LeapYearShift) / 7+ 1;
end;
$$;
ПРИМЕЧАНИЕ
1 + (IsLeapYear(currentYear) and $1 > make_date(currentYear, 2, 28))::int
означает, что в этом году LeapYear нужно минус больше на один день (29 февраля),Пусть дни LeapYear совпадают с обычным годом.
SQLFIDDLE