在Delphi中复制SQL Server DATEPART(wk,...)函数

时间:2017-11-02 22:54:43

标签: sql-server date delphi

德尔福的WeekOfTheYear函数使用ISO 8601方法,其中一周从星期一开始,一年的第一周定义为该年有四天或更多天的第一周。< / p>

要获得Microsoft SQL Server中一年中的一周,您可以使用DATEPART(wk, ...)函数,但这会使用不同的机制,因为美国英语的默认值在星期日开始,第二周开始今年的第一个星期日,除非那个星期日是1月1日,然后第二个星期从一年的第2个星期日开始,如果你运行这个例子可以看出:

SELECT '2010-1-3', DATEPART(wk, '2010-1-3'), DATENAME(dw, '2010-1-3')
SELECT '2011-1-2', DATEPART(wk, '2011-1-2'), DATENAME(dw, '2011-1-2')
SELECT '2012-1-1', DATEPART(wk, '2012-1-1'), DATENAME(dw, '2012-1-1')
SELECT '2013-1-6', DATEPART(wk, '2013-1-6'), DATENAME(dw, '2013-1-6')
SELECT '2014-1-5', DATEPART(wk, '2014-1-5'), DATENAME(dw, '2014-1-5')
SELECT '2015-1-4', DATEPART(wk, '2015-1-4'), DATENAME(dw, '2015-1-4')
SELECT '2016-1-3', DATEPART(wk, '2016-1-3'), DATENAME(dw, '2016-1-3')
SELECT '2017-1-1', DATEPART(wk, '2017-1-1'), DATENAME(dw, '2017-1-1')
SELECT '2018-1-7', DATEPART(wk, '2018-1-7'), DATENAME(dw, '2018-1-7')
SELECT '2019-1-6', DATEPART(wk, '2019-1-6'), DATENAME(dw, '2019-1-6')
SELECT '2020-1-5', DATEPART(wk, '2020-1-5'), DATENAME(dw, '2020-1-5')

上述结果表明,每个星期日都是一年中的第二周,除了1月1日,即一年中的第一周。

我看了下面这个问题的答案,这似乎表明它会在一周的哪一天取决于一周开始的那一天,

Delphi week number function based on system start of week

但这也是基于使用Delphi函数,并且不会返回与SQL Server相同的结果。

SQL Server当前显示2018年1月1日至2018年1月8日的日期是:

1/1/2018 = 1
2/1/2018 = 1
3/1/2018 = 1
4/1/2018 = 1
5/1/2018 = 1
6/1/2018 = 1
7/1/2018 = 2
8/1/2018 = 2

Delphi确实有一个DayOfWeek函数,它使用星期日作为一周的第一天,与使用星期一的DayofTheWeek函数相比,但我似乎无法解决这个问题。获得与SQL Server相同结果所需的逻辑。至少有一个条件是处理1月1日星期日是第1周,但是第一个星期日是第2周。

是否有人使用任何Delphi源代码返回一年中的一周,正如SQL Server在使用美国英语默认值DATEFIRST 7时所做的那样?

1 个答案:

答案 0 :(得分:1)

代码看似简单,但它的逻辑有点困难。关于第一个星期日的规则意味着,在所有情况下,第一个星期六是在第1周。所以我们的想法是,我们去下一个星期六并计算从年初开始的星期六的数量。

function SQLWeekOfYear(const pDate: TDate): integer;
var
  iYear, iMonth, iDay : word;
  iDOW : integer;
  iDays : integer;
begin
  // this is based on First Sunday in year being in week 2
  // unless it is the first of Jan, which is equivalent of saying that the
  // first saturday is always in week 1.
  //
  // This means that we count the number of saturdays prior to this date and add one,
  // which is equivalent to finding the next saturday
  DecodeDate( pDate, iYear, iMonth, iDay );
  iDOW := DayOfWeek( pDate );
  // Find how many days so far since 1st jan
  iDays := Trunc(pDate - EncodeDate( iYear, 1, 1 )) + 1;
  // now adjust for day of week to get to next saturday
  iDays := iDays + (7-iDOW);
  // add 6 and divide by 7 to find actual number saturdays
  Result := (iDays + 6) div 7;
end;