使用PostgreSQL 9.4.18版,PostGIS 2.2版 我正在使用此功能,并且正在使用WW,因为不需要ISO周数...仅从1月1日开始的周数:
CREATE FUNCTION f_woy(timestamp with time zone) RETURNS int LANGUAGE sql
IMMUTABLE AS $$SELECT to_char($1, 'WW')::int$$;
当我运行以下查询时,每隔4年,星期数就会更改为a年。我试图在某个日期每年都获得一致的周数。例如,当我跑步时
SELECT f_woy(('2007-06-24 14:19:46.502-07'::timestamp at time zone 'UTC' at
time zone 'america/los_angeles')::date)
在2004年,2005年,2006年和2007年,我得到了:
woy integer
25
但是当我以以下方式运行它时:
SELECT f_woy(('2008-06-24 14:19:46.502-07'::timestamp at time zone 'UTC' at
time zone 'america/los_angeles')::date)
我知道
woy integer
26
有没有一种方法可以忽略the年,并使所有内容保持一致,因此所有06-24都将是第25周。我看到了一些有关确定是否为a年的帖子,但我有很难集成该逻辑,以便将其应用于检查周数的所有查询。
答案 0 :(得分:1)
您可以使用CASE WHEN
表达式来检查今年是不是<>> le年
判断leap年公式为
(年%4 = 0)和(年%100 <> 0)或(年%400 = 0)
在CASE WHEN
条件下添加此公式即可
看起来像这样。
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
功能时,of年的星期与正常年份的星期相同。
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
编辑
Le年意味着今年将添加2月29日,因此您可以尝试使用它。
IsLeapYear
函数将今年定为leap年或不是leap年。
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 ,则需要减少一天的时间(2月29日)。让 LeapYear 的天数与正常年份相同。