Bienvenue à Blogs CodeS-SourceS Identification | Inscription | Aide

SQL Server : Comment calculer l'age du capitaine (différences sur des dates) ?

Comment calculer la différence d'une date par rapport à une autre avec SQL Server, le tout en année ou en mois ?

Rien de plus simple me direz vous, la réponse c'est DATEDIFF :

DECLARE

@debut datetime
DECLARE
@fin
datetime

SET
@debut = '20070404'
SET @fin =
'19780404'

SELECT DATEDIFF(YEAR, @fin, @debut)

Pas de problème ici j'ai bien eu 29 ans cette année (je me fais vieux je sais)...
Mais remplaçons 20070404 par 20070403... La veille de mon anniversaire d'après SQL Server j'avais déjà 29 ans ????

Pourquoi, parce que SQL Server fait uniquement la différence sur la composante année de la date résultat, il y a une période où votre age est faux ! Le problème est le même en réalisant la différence avec les mois.

Pour ne pas vieillir avant l'heure voici une méthode juste pour réaliser ce calcul (ce n'est sans doute pas la seule, mais l'une des plus éfficaces)

DECLARE @debut datetime
DECLARE
@fin
datetime

SET
@debut =
'20070403'
SET @fin =
'19780404'

SELECT (0 + CONVERT(char(8),@debut,112) - CONVERT(char(8),@fin,112)) / 10000

L'idée est de soustraire la date en format YYYYMMDD ou AAAAMMJJ et de tronquer le résultat pour obtenir l'age.
Le 0 + n'est là que pour réaliser une conversion implicte.
C'est Steve Kass autre MVP Server qui est l'inventeur de cette formule fort utile. Merci à lui !

Pour le calcul de la différence sur des jours, celà donne :

DECLARE @debut datetime
DECLARE
@fin datetime

SET
@debut = '19780404'
SET @fin = '20070403'

SELECT DATEDIFF(DAY, @debut, @fin)


Merci à Cédric pour le calcul.

Bon calcul...

Ce post vous a plu ? Ajoutez le dans vos favoris pour ne pas perdre de temps à le retrouver le jour où vous en aurez besoin :
Publié lundi 2 juillet 2007 20:39 par christian
Classé sous : ,

Commentaires

mardi 3 juillet 2007 04:50 by Matthieu MEZIL

# re: SQL Server : Comment calculer l'age du capitaine (différences sur des dates) ?

Excellent !

Merci Christian.

mardi 3 juillet 2007 09:30 by Jem

# re: SQL Server : Comment calculer l'age du capitaine (différences sur des dates) ?

???? Pardon ???

Ce qui nous amènera à la conclusion logique qu'il y a 89 mois entre le 03/12/2007 et le 03/01/2008 ?

L'utilité des fonctions de date comme DATEDIFF n'est elle pas justement de prendre en compte toutes les petite facéties du calendrier (12 mois par an, mois de 28,29,30 ou 31 jours...) ?

mardi 3 juillet 2007 10:12 by Matthieu MEZIL

# re: SQL Server : Comment calculer l'age du capitaine (différences sur des dates) ?

"Et comment obtenir la différence en nombre de mois, remplacez 10000 par 100 !" Tu es sûr de toi ? Je pense que tu te trompes.

mardi 3 juillet 2007 10:36 by Matthieu MEZIL

# re: SQL Server : Comment calculer l'age du capitaine (différences sur des dates) ?

Je confirme c'est pas divisé par 100 (il n'y a pas 100 mois dans un an). Pour avoir l'écart en années, mois, jours, je l'ai fait (en C#) ici :

http://blog.developpez.com/index.php?blog=121&title=ecart_de_date_en_sql_pas_datediff&more=1&c=1&tb=1&pb=1

mardi 3 juillet 2007 13:56 by Jem

# re: SQL Server : Comment calculer l'age du capitaine (différences sur des dates) ?

Le problème c'est qu'une différence ne peut être exacte au delà du jour (à la rigueur de la semaine) : Une différence "exacte" de 1 mois ne veut rien dire vu qu'1 mois peut désigner de 28 à 31 jours.

De même une différence "exacte" en année ne donne rien, une année pouvant avoir 365 ou 366 jours.

Je pense que c'est la raison pour laquelle le type TimeSpan ne donne pas d'unité plus grande que le jour.

Dans ce cas, la solution de SQL Server (qui est simplement de compter le nombre de fois ou on change l'unité voulue.

mardi 3 juillet 2007 14:08 by Jem

# re: SQL Server : Comment calculer l'age du capitaine (différences sur des dates) ?

Sinon si on veut s'embeter il faut faire un algo de ce type :

Declare @DtDeb datetime,@DtFin datetime

Set @DtDeb='01/02/2006'

Set @DtFin='13/02/2007'

Declare @DtTmp datetime,

@nbAn int, @nbMois int, @nbJour int

Set @nbAn = Datediff(year,@DtDeb,@DtFin)

Set @DtTmp = Dateadd(year,@nbAn,@DtDeb)

IF @DtTmp>@DtFin BEGIN

Set @NbAn=@NbAn-1

Set @DtTmp = Dateadd(year,-1,@DtTmp)

END

Set @NbMois = Datediff(month,@DtTmp,@DtFin)

Set @DtTmp = Dateadd(month,@nbMois,@DtTmp)

IF @DtTmp>@DtFin BEGIN

Set @NbMois=@NbMois-1

Set @DtTmp = Dateadd(month,-1,@DtTmp)

END

Set @NbJour = Datediff(day,@DtTmp,@DtFin)

Print 'Durée de  '

+ cast(@NbAn as varchar(3)) + ' années '

+ cast(@NbMois as varchar(3)) + ' mois et '

+ cast(@NbJour as varchar(3)) + 'jours'

mardi 3 juillet 2007 14:46 by christian

# re: SQL Server : Comment calculer l'age du capitaine (différences sur des dates) ?

Petite erreur de ma part sur les mois... Je ne retrouve plus la formule en question...

Par contre le DateDiff de SQL ne se base que sur la composante qui le concerne, il fait pour l'année 2007 - 1978... Il ne tient pas compte des facécies du calendrier

Pour le dernier algo, c'est celui qu'on trouve habituellement, mais il est bcp plus lent que celui de ce post...

mardi 3 juillet 2007 15:26 by Benoît NOËL

# re: SQL Server : Comment calculer l'age du capitaine (différences sur des dates) ?

Personnellement je préfère la formule suivante qui a l'avantage de marcher pour les différents formats de date reconnus implicitement par SQL (et en plus elle me paraît plus pédagogique par rapport à ce que fait DateDiff :

SELECT (DATEDIFF(MONTH, @Debut, @fin) - CASE WHEN DAY(@Debut) > DAY(@fin) THEN 1 ELSE 0 END)/12

La partie entre parenthèse donne le nombre de mois !

mercredi 4 juillet 2007 00:42 by Rui

# re: SQL Server : Comment calculer l'age du capitaine (différences sur des dates) ?

Pour ma part, j'aime bien utiliser les fonctions sql uniquement pour ce genre de calculs, ce qui peut donner des solutions peut-etre un peu tordues...

SELECT    DATEDIFF(YEAR,CAST(0 AS DATETIME),CAST(DATEDIFF(DAY,@Debut,@Debut)-1 AS DATETIME))

J'en ai profité pour poster un petit billet en complément de celui-ci:

http://www.1024b.com/2007/07/sql-jouons-avec-les-dates-2.html

Les commentaires anonymes sont désactivés

Les 10 derniers blogs postés

- Silverlight 3 : Communication et multicast par Kévin Gosse le il y a 25 minutes

- [Perso] Découvertes estivales : Linux (Part I) par Le blog de FremyCompany le il y a 3 heures et 7 minutes

- [Refactoring] ReSharper pour Visual Studio 2010 (Preview) par Thomas Jaskula le il y a 17 heures et 43 minutes

- [Refactoring] Analyser vos exceptions avec ReSharper Exceptional par Thomas Jaskula le il y a 18 heures et 57 minutes

- SharePoint 2007 : patterns & practices SharePoint Guidance par Philippe Sentenac [MVP SharePoint] le 07-03-2009, 09:56

- [Visual Studio 2010] Les tests cases c’est bien, mais je vais devoir tout réécrire ? par Etienne Margraff le 07-03-2009, 09:00

- MVP[Gribouillon].AddYear par The Grib's Lair [Sébastien PICAMELOT - MVP SharePoint] le 07-03-2009, 08:45

- Clinique INSIA - Projet de fin d’Etudes (Silverlight 3 MVVM et OutOfBrowser, WCF, TFS) - Part 1 par David REI le 07-02-2009, 23:38

- C’est la crise ? Bah pourquoi cramer du budget pub alors ? par Nix's Blog le 07-02-2009, 15:31

- Soyons MVP ! par TheSaib .NET blog le 07-02-2009, 12:15