Please start any new threads on our new site at https://forums.sqlteam.com. We've got lots of great SQL Server experts to answer whatever question you can come up with.

 All Forums
 SQL Server 2000 Forums
 Transact-SQL (2000)
 Week numbers ?

Author  Topic 

gispro
Starting Member

21 Posts

Posted - 2006-01-18 : 05:04:41
I have a question about calculation of week numbers from dates, generally and in MS/SQL 2000.

E.g., what week numbers do January 1st, 2006 and 2005 belong to ?

According to the Danish almanac, 1/1/06 belongs to week 52 in 2005, and 1/1/05 belongs to week 53 in 2004. And Danish weeks start on Monday, not Sunday.

I'm unable to get the built-in function DATEPART(ww,..) to return this, regardless of how I set the DATEFIRST parameter. It seems MS/SQL only makes a simple division by 7 on the day-in-year, rounding the result up, always considering 1/1 to be in week number 1.

Are week numbers caclulated differently in the US, or is something else amiss ? Are there any additional global settings that I need to set ?

Or am I forced to build my own function using @@DATEFIRST etc. ??


--
GisPro

TG
Master Smack Fu Yak Hacker

6065 Posts

Posted - 2006-01-18 : 05:30:39
Sql server's weeks are not really based on business rules. It is more like simply deviding a calendar year into 7 day units. @@Datefirst setting will just define the unit devisions. Any given date will not belong to a week in a different year. So a week that falls at the end and beginning of the year will usually be a "short" week. So you will probably need to either write your own logic or use a "custom" calendar table that includes a weeknumber column.

Be One with the Optimizer
TG
Go to Top of Page

Michael Valentine Jones
Yak DBA Kernel (pronounced Colonel)

7020 Posts

Posted - 2006-01-18 : 09:32:51
It looks like the week number you are seeing is actually the ISO 8601 week of year. You can use Google to see the exact algorithim for this. Basically, the first week of a year starts with the first Monday on or before January 4th of each year, and can begin anywhere from Dec 29 of the prior year through Jan 4.

CODO ERGO SUM
Go to Top of Page

druer
Constraint Violating Yak Guru

314 Posts

Posted - 2006-01-18 : 15:32:20
Why do accountants get to make such complicated/silly rules? If you asked a first grader what January 1, 2006 was they would tell you that it was the first day of the year. It takes a college degree, MBA and passing a test for someone to be able to suggest that January 1, 2006 is in a week for 2005. :)

I bought two cans of beans. (Leased 2 cans of beans I should never buy them right.) How would they respond if I said I asked them which can of beans does the first bean belong to that I pull out of the second can? Would they say you need to count how many beans were in the first can first to see if you were a bean short?

Here is my thought process, some weeks (like Week 52 in 2005) may be a few days short. January 1, 2006 belongs to the year 2006 and can't be "borrowed" to make up for a short week in 2005. Those accountants have screwed up enough other things, please keep them away from my SQL Server. In SQL us "logical" minded folks get to make the rules. :)
Go to Top of Page

Michael Valentine Jones
Yak DBA Kernel (pronounced Colonel)

7020 Posts

Posted - 2006-01-18 : 15:51:09
quote:
Originally posted by druer
Why do accountants get to make such complicated/silly rules?...


I don't know that you can blame accountants for this, but if you really want to know about this stuff, be my guest...

http://www.iso.org/iso/en/prods-services/popstds/datesandtime.html

http://en.wikipedia.org/wiki/ISO_8601






CODO ERGO SUM
Go to Top of Page

jsmith8858
Dr. Cross Join

7423 Posts

Posted - 2006-01-18 : 15:51:28
quote:
Originally posted by druer

Why do accountants get to make such complicated/silly rules? If you asked a first grader what January 1, 2006 was they would tell you that it was the first day of the year. It takes a college degree, MBA and passing a test for someone to be able to suggest that January 1, 2006 is in a week for 2005. :)

I bought two cans of beans. (Leased 2 cans of beans I should never buy them right.) How would they respond if I said I asked them which can of beans does the first bean belong to that I pull out of the second can? Would they say you need to count how many beans were in the first can first to see if you were a bean short?

Here is my thought process, some weeks (like Week 52 in 2005) may be a few days short. January 1, 2006 belongs to the year 2006 and can't be "borrowed" to make up for a short week in 2005. Those accountants have screwed up enough other things, please keep them away from my SQL Server. In SQL us "logical" minded folks get to make the rules. :)



What does SQL Servers implementation of week number calculations have to do with accounting?
Go to Top of Page

X002548
Not Just a Number

15586 Posts

Posted - 2006-01-18 : 16:03:31
Actually, it looks like 1/1/05 belongs to week 52 of 2004.

I would consider them weak numbers

It appears that Sundat in SQL Server starts the week, such that the first "week" in 2005 in SQL Server only had 1 day


SELECT DATEPART(WW,'1/1/2005')
, DATEPART(WW,'1/2/2005')
, DATEPART(WW,'1/7/2005')
, DATEPART(WW,'1/8/2005')
, DATEPART(WW,'12/30/2005')
, DATEPART(WW,'12/31/2005')




Brett

8-)

Hint: Want your questions answered fast? Follow the direction in this link
http://weblogs.sqlteam.com/brettk/archive/2005/05/25/5276.aspx

Add yourself!
http://www.frappr.com/sqlteam
Go to Top of Page

Michael Valentine Jones
Yak DBA Kernel (pronounced Colonel)

7020 Posts

Posted - 2006-01-18 : 16:34:42
quote:
Originally posted by X002548
Actually, it looks like 1/1/05 belongs to week 52 of 2004.



The ISO 8601 beginning of year for 2004 is the first Monday on or before 2004-1-4, which is 2003-12-29. The difference in days between 2003-12-29 and 2005-1-1 = 369. Dividing 369 by 7 gives you 52. Adding 1 to 52 = 53 to allow for starting the week number at 1 instead of zero. So 2005-1-1 is in week 53 of year 2004, just like gispro saw in his Danish almanac.

CODO ERGO SUM
Go to Top of Page

gispro
Starting Member

21 Posts

Posted - 2006-01-18 : 16:51:05
What day starts the week differs from country to country afaik, and SQL Server has the DATEFIRST to account for it. If you set DATEFIRST to 4 (= Thursday starts the week), DATEPART(dw,'some Friday') will return 2 as it should.

In any case, I ended up building my own function. I've done it in php previously, so I had the quirks ironed out already. I did look at a few algorithms I found via Google as suggested by Michael, but they were too general and off-mark for my taste.

Thanks for the help guys. I didn't even know that ISO-8601 existed :-)

--
GisPro
Go to Top of Page

Michael Valentine Jones
Yak DBA Kernel (pronounced Colonel)

7020 Posts

Posted - 2006-01-18 : 17:01:11
If you are using the ISO standard, then the day that starts the week does not vary from country to country. It is always Monday.

In the US, most people think of the week as starting on Sunday, but that can vary. It is very common to use the ISO week for manufacturing, since the work week starts on Monday also, and it gives each week a unique number that is the same world wide.



CODO ERGO SUM
Go to Top of Page

Michael Valentine Jones
Yak DBA Kernel (pronounced Colonel)

7020 Posts

Posted - 2006-01-18 : 20:52:01
I posted a SQL function, dbo.F_ISO_WEEK_OF_YEAR, that does this in the Script Library forum:

http://www.sqlteam.com/forums/topic.asp?TOPIC_ID=60510





CODO ERGO SUM
Go to Top of Page

gispro
Starting Member

21 Posts

Posted - 2006-01-19 : 08:34:16
Very slick Michael, respect ! :-) Mine's way more clunky.

My next task is a function that'll return the start of a week (as datetime) given as year + week number. Can you conjure up a similar slick function for that too ? ;-)

It's for generating weekly reports with Reporting Services, btw, of time stamped data.

--
GisPro
Go to Top of Page

jsmith8858
Dr. Cross Join

7423 Posts

Posted - 2006-01-19 : 10:01:58
I think that, by far, the easiest way to do this is to create a permanent table of Weeks in your database, covering a wide range of years (say, up to 2050 or something) and to put in there date ranges and anything else that you need. This will make your SQL statements more efficient by allowing the use of indexes, rather than using a UDF. In addition, you will be able to use this table to drive SELECT's that return 1 row per week or anything like that, in addition to quickly returning information such as the date range of week x of year y.

The best thing about a table is that you can manually edit any percular rules that you need to enforce about how your weeks are calculated; you might use a UDF like Michaels to initially build it, but once it is there you can implement whatever business rules you need without worrying about writing the proper calculations for it.
Go to Top of Page

Michael Valentine Jones
Yak DBA Kernel (pronounced Colonel)

7020 Posts

Posted - 2006-01-19 : 10:34:05
You can turn this into a function:


-- Script to find first day of week for an ISO year and week

declare @year int
declare @week int

-- Pick a year and week
select @year = 2005
select @week = 52

select
StartOfYearWeek =
-- If it is in the year passed,
-- return start of week,
-- otherwise, return null.
case
when @week < 1
then null
when dateadd(dd,(@week-1)*7,CurrYrStart) < NextYrStart
then dateadd(dd,(@week-1)*7,CurrYrStart)
else null
end
from
(
select
-- First day of first week of current year
CurrYrStart =
dateadd(dd,(datediff(dd,-53690,aa.Jan4)/7)*7,-53690),
-- First day of first week of next year
NextYrStart =
dateadd(dd,(datediff(dd,-53690,dateadd(yy,1,aa.Jan4))/7)*7,-53690)
from
(
select
--Find Jan 4 for input year
Jan4 =
case
when @year between 1753 and 9998
then dateadd(dd,3,dateadd(yy,@year-1900,0))
-- Null if not in valid year range
else null end
) aa
) a




CODO ERGO SUM
Go to Top of Page

Michael Valentine Jones
Yak DBA Kernel (pronounced Colonel)

7020 Posts

Posted - 2006-01-19 : 10:38:41
quote:
Originally posted by jsmith8858

I think that, by far, the easiest way to do this is to create a permanent table of Weeks in your database,...


I agree with that, although our table is for individual dates. I actually pulled the logic for the UDF from the stored procedure I use to load our table.

CODO ERGO SUM
Go to Top of Page

jsmith8858
Dr. Cross Join

7423 Posts

Posted - 2006-01-19 : 10:44:26
quote:
Originally posted by Michael Valentine Jones

quote:
Originally posted by jsmith8858

I think that, by far, the easiest way to do this is to create a permanent table of Weeks in your database,...


I agree with that, although our table is for individual dates. I actually pulled the logic for the UDF from the stored procedure I use to load our table.

CODO ERGO SUM



That's probably even better and more efficient; also, it will help you with SELECT's that need to return 1 row per day if those are required.
Go to Top of Page
   

- Advertisement -