Le calcul du numéro de semaine, TSQL
Par Arian Papillon le jeudi 19 janvier 2012, 18:41 - Lien permanent
Quelle prise en charge de notre mode de calcul à la norme ISO et comment obtenir le bon numéro de semaine à partir d'une date avec TSQL ?
Selon la norme ISO-8601 appliquée en France et adoptée par la plupart des pays européens, la semaine 1 est la première série de 4 jours dans l'année (la semaine commençant le lundi) :
- c’est donc celle qui contient le premier jeudi de l’année et le 4 janvier
- si le jour de l’an arrive après le jeudi, il se situe donc dans la dernière semaine de l’année précédente
- le nombre de semaines de l’année peut être 52 ou 53 - une semaine n’est affectée qu’à une seule année
- cette année 2012, le premier janvier tombant un dimanche faisait donc partie de la semaine 52 de l’an dernier, et la semaine 1 commence le 2 janvier...
Aux US, la semaine commence le dimanche et la semaine 1 est celle contenant le 1er janvier (et aussi le premier samedi de l’année).
- Une semaine peut donc être affectée deux fois, à la nouvelle année et à l’année précédente
- Cette année 2012, le premier janvier tombant un dimanche était donc le premier jour de la semaine 1 ...
D’autres modes de calcul peuvent exister ailleurs, comme par exemple :
- Un jour de début de semaine différent (le samedi), ou bien la semaine 1 est la première semaine entière de l’année
TSQL
En ce qui nous concerne pour calculer nos numéros de semaine ISO-8601, SQL Server 2008 offre l'option utile ISO_WEEK avec la fonction DATEPART :
- SELECT DATEPART (ISO_WEEK, ‘20120101’) renvoie 52
- SELECT DATEPART(ww,’20120101’) renvoie 1
Mais si vous n’êtes pas passé à SQL Server 2008, il faut faire le calcul. Chacun sa méthode, voici la mienne :
CREATE FUNCTION dbo.iso_week ( @thedate DATETIME )
RETURNS INT
AS BEGIN
DECLARE @weeknumber INT
-- cas général
SET @weeknumber = DATEPART(ww, @thedate) -
CASE WHEN
DATEPART(dw,
DATEADD(dd,
-( DATEPART(dy, @thedate) -
1 ), @thedate)) > 4
THEN 1
ELSE 0
END
-- cas des premiers jours de l'année
IF @weeknumber = 0
SET @weeknumber = dbo.iso_week(DATEADD(dd, -1,
@thedate))
-- cas des derniers jours appartenant à l'année
suivante
RETURN CASE WHEN DATEPART(mm, @thedate) = 12 AND
DATEPART(dd, @thedate) - DATEPART(dw, @thedate) >= 28
THEN 1
ELSE @weeknumber
END
END
GO
A voir, cette autre méthode plus élégante que la mienne sur ce blog.
Commentaires
Salut Arian!
Tu pourrais pas nous faire aussi le script pour l'année ISO?
Parce que si la semaine 1-2012 devient la semaine 53, il ne faut pas oublier de changer également l'année, sinon on bascule sur la semaine 53-2012 qui n'est pas vraiment la même
En tout cas merci pour l'info!