Friday, January 28, 2011

Get the number of years, months & days for the given 2 dates

declare 
 @dt1 datetime,
 @dt2 datetime,

 @yr int,
 @mth int,
 @day int,

 @yr_count int,
 @mth_count int,
 @day_count int,

 @month_end datetime,
 @month_begin datetime

-- test cases
select 

-- 30 days  <== same yr/month
--@dt1 = '20101202', @dt2 = '20101231' 

-- 1 month <== same yr/month
--@dt1 = '20101201', @dt2 = '20101231'    

-- 1 year.<== same yr & diff mth, start date is 1st.
--@dt1 = '20100101', @dt2 = '20101231'    

-- 2 month, 25 days<== same yr & start date is 1st.
--@dt1 = '20100101', @dt2 = '20100325'   

-- 1 month, 1 day <== diff yr & diff mth
--@dt1 = '20101202', @dt2 = '20110102'   

-- 3 months, 0 day. <== same yr & diff mth
--@dt1 = '20100502', @dt2 = '20100801'   

-- 1 month, 30 day   <== same yr & diff mth
@dt1 = '20101102', @dt2 = '20101231'   

-- 2 months, 0 day   <== diff yr & diff mth
--@dt1 = '20101102', @dt2 = '20110101'   

-- 1yr, 2 months, 0 day   <== diff yr & diff mth
--@dt1 = '20101102', @dt2 = '20120101'   

select 
 @dt1 as 'start date',
 @dt2 as 'end date'

-- get all the differences for further analysis
select
 @yr_count = datediff(year, @dt1,@dt2),
 @mth_count = datediff(month, @dt1,@dt2),
 @day_count = datediff(day, @dt1, @dt2)

-- see if we should retain the year counter.
if (@yr_count - 1 >= 0)
begin
 select @yr_count = @yr_count - 1 
end

-- ensure that the month counter is less than 12.
if @mth_count % 12 <> 0
begin
 select @mth_count = @mth_count % 12
end

-- get first day of the month for the 2nd date.
select
 @month_begin = cast(year(@dt2) as varchar(4)) 
    + case when month(@dt2) > 9 then cast(month(@dt2) as varchar(2))
     else '0' + cast(month(@dt2) as varchar(2))
     end
    + '01'

-- get the last day of the month for the 2nd date.
select 
 @month_end = dateadd(day, -1, dateadd(month, 1, @month_begin))

if (@dt1 = @month_begin) and (@dt2 = @month_end) 
begin
 select 
  @mth_count = @mth_count + 1,
  @day_count = 0

--select @month_begin, @month_end
end
else 
begin
 if @dt1 > @month_begin
  select @month_begin = @dt1

--select @month_begin, @month_end, @dt2

 -- if the end date is the last day of the month
 -- and the start date is the first day of the month,
 -- the day counter will be zero and the month counter increase by 1.
 if (@dt2 = @month_end) and day(@dt1) = 1
 begin
  select 
   @mth_count = @mth_count + 1,
   @day_count = 0

--select @day_count

 end
 else
 begin
  -- update the day counter.
  select @day_count = datediff(day, @month_begin, @dt2) + 1 

 end
end

if  (@mth_count <> 0) and (@mth_count % 12 = 0)
begin

 declare @i int
 select  @i = @yr_count +(@mth_count / 12)

 select 
  @mth_count = 0,
  @yr_count = @i

end

if month(@dt1) <> month(@dt2)
begin

 if day(@dt1) <> 1 and @day_count > 0
  select @day_count = @day_count - 1

end

-- ----------------------------------------------
select
 @yr_count as '# of years',
 @mth_count  as '# of months',
 @day_count as '# of days'