Dans un projet récent, une exigence consistait à indiquer quand une ressource serait entièrement consommée. En plus de la date du calendrier de l'épuisement, on m'a demandé de montrer le temps restant au format anglais, quelque chose comme "1 an, 3 mois."
La DATEDIFF
fonction intégrée
Renvoie le nombre ... des limites de partie de date spécifiées croisées entre la date de début et la date de fin spécifiées.
Si utilisé tel quel, cela pourrait produire des résultats trompeurs ou déroutants. Par exemple, l'utilisation d'un intervalle de YEAR montrerait que 1999-12-31 (YYYY-MM-DD) et 2000-01-01 sont à un an d'intervalle alors que le bon sens dirait que ces dates ne sont séparées que d'un jour. À l'inverse, en utilisant un intervalle de JOUR 1999-12-31 et 2010-12-31 sont séparés de 4 018 jours alors que la plupart des gens verraient "11 ans" comme une meilleure description.
En partant du nombre de jours et en calculant les mois et les années à partir de là, il y aurait des erreurs d'année bissextile et de taille de mois.
Je me suis demandé comment cela pouvait être implémenté dans les différents dialectes SQL? Un exemple de sortie comprend:
create table TestData(
FromDate date not null,
ToDate date not null,
ExpectedResult varchar(100) not null); -- exact formatting is unimportant
insert TestData (FromDate, ToDate, ExpectedResult)
values ('1999-12-31', '1999-12-31', '0 days'),
('1999-12-31', '2000-01-01', '1 day'),
('2000-01-01', '2000-02-01', '1 month'),
('2000-02-01', '2000-03-01', '1 month'), -- month length not important
('2000-01-28', '2000-02-29', '1 month, 1 day'), -- leap years to be accounted for
('2000-01-01', '2000-12-31', '11 months, 30 days'),
('2000-02-28', '2000-03-01', '2 days'),
('2001-02-28', '2001-03-01', '1 day'), -- not a leap year
('2000-01-01', '2001-01-01', '1 year'),
('2000-01-01', '2011-01-01', '11 years'),
('9999-12-30', '9999-12-31', '1 day'), -- catch overflow in date calculations
('1900-01-01', '9999-12-31', '8099 years 11 months 30 days'); -- min(date) to max(date)
Il se trouve que j'utilise SQL Server 2008R2, mais je suis intéressé d'apprendre comment d'autres dialectes géreraient cela.