【问题标题】:How can I getting for consistent week number from leap year or normal year如何从闰年或正常年获得一致的周数
【发布时间】:2018-06-24 07:14:12
【问题描述】:

使用 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 年,周数会发生变化,这是闰年。我试图在某个日期每年获得一致的周数。所以,例如,当我跑步时

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,我得到:

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

有没有办法我可以忽略闰年并保持一切一致,以便所有 06-24 都是第 25 周。我看到一些关于确定是否是闰年的帖子,但我有很难集成该逻辑,以便我可以将其应用于我正在检查周数的所有查询。

【问题讨论】:

  • 我不明白你在找什么。我知道的所有周数定义(ISO 或非 ISO,从星期日或星期一开始的星期)都无法实现一年中的同一天具有相同的周数。这与闰年无关。它还会影响一月和二月的日期。这与年份从不同的工作日开始这一事实有关。
  • 1 月 1-7 日...第 1 周。1 月 8-14 日...第 2 周。1 月 15-21 日...第 3 周。这是我一直在寻找的一致性。我想忽略 2 月 29 日,这会破坏一致性。我不在乎一年的星期几开始。 1 月 1 日至 7 日始终是第 1 周。12 月 25 日至 31 日始终是第 52 周。

标签: sql postgresql


【解决方案1】:

您可以使用CASE WHEN 表达式来检查今年是否是闰年

  1. 今年是闰年返回结果减1。
  2. 今年不是闰年返回结果。

判断闰年公式是

(年 % 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 函数时,闰年的周与平年的周相同。

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

编辑

闰年表示今年会增加2月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 &gt; make_date(currentYear, 2, 28))::int 表示如果今年是闰年,则需要多减去一天(2 月 29 日)。让闰年的日子与正常年份相同。

SQLFIDDLE

【讨论】:

  • 这适用于闰日之后的几个月(3 月及之后),但 1 月和 2 月显示一年中的不同周(偏移 1)。我尝试添加这个条件语句:(date_part('month',$1)::int > 2),它适用于 2 月,但不适用于 5 月 24 日。有什么想法吗? dbfiddle.uk/…
  • 谢谢!!!我将其标记为工作,因为对于大多数实际目的来说它是完美的。但是,我注意到如果我将 12 月 31 日作为日期,它会显示为第 53 周而不是第 52 周。有什么想法吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-12-10
  • 2015-11-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多