[ horabin @ 28.05.2008. 11:30 ] @
Pokusao sam da napravim funkciju za izracunavanje tacne razlike u datumima izrazene u mjesecima i godinama. Ulazni parametri su dva datuma i uslov na osnovu kojeg se odlucuje da li se racunaju datumi ili mjeseci. Napominjem da mi treba tacna razlika u mjesecima i danima, znaci ako je prestupna godina treba uzeti u obzir da februar ima 29 dana. Unaprijed hvala.

ALTER FUNCTION [PK].[test]
(
@datumOd datetime,
@datumDo datetime,
@broj tinyint
)
RETURNS tinyint


AS
BEGIN

declare @d tinyint;
declare @m tinyint;
declare @y tinyint;
declare @res tinyint;
declare @test bit;

set @m = 0;
SET @m = @m + 1;
set @test = 0;
set @datumOd = dateadd("Day",31,@datumOd);

while (@test = 0)
BEGIN
if ((datepart(month,@datumOd))in(1,3,5,7,8,10))
BEGIN
if (datediff(day,@datumOd,@datumDo)<31)
break;
else
BEGIN
select @datumOd = dateadd("Day",31,@datumOd);
set @m = @m + 1;
CONTINUE;
END
END

if (datepart(month,@datumOd)in(4,6,9,11))
BEGIN
if (datediff(day,@datumOd,@datumDo)<30)
break;
else
BEGIN
set @datumOd = dateadd("Day",30,@datumOd);
set @m = @m + 1;
CONTINUE;
END
END

if (datepart(month,@datumOd)=2 and year(@datumOd)%4=0)
BEGIN
if (datediff(day,@datumOd,@datumDo)<29)
break;
else
BEGIN
set @datumOd = dateadd("Day",29,@datumOd);
select @m = @m + 1;
CONTINUE;
END
END

if (datepart(month,@datumOd)=2 and year(@datumOd)%4>0)
BEGIN
if (datediff(day,@datumOd,@datumDo)<28)
break;
else
BEGIN
set @datumOd = dateadd("Day",28,@datumOd);
select @m = @m + 1;
CONTINUE;
END
END
END


set @d = datediff(day, @datumOd, @datumDo);
if (@broj = 1)
select @res = @m;
if (@broj = 2)
select @res = @d;
return @res;

END
[ deerbeer @ 28.05.2008. 12:02 ] @
Funkcija racuna tacnu razliku za 2 zadata datuma i
bila mi je potrebna za jednu HR aplikaciju gde se upravio trazila preciznost u izracunavanju ...
Mozda ce ti ovo pomoci ....

Code:

CREATE  FUNCTION  RadniStaz (@DatumOd datetime , @DatumDo datetime)
RETURNS @Staz TABLE (god int ,mes int ,dan int )
AS
begin 

declare @finalYears int 
DECLARE @finalmonths int 
DECLARE @finalDays int 
DECLARE @rawmonths int 
DECLARE @realmonths int 
DECLARE @tempdate datetime 



IF DATEPART(month,@DatumOd) = DATEPART(month,@DatumDo) AND DATEPART(year,@DatumOd) = DATEPART(month,@DatumDo) 
    BEGIN 
    SET @finalYears = 0 
         IF DATEPART(month,@DatumOd) <> DATEPART(month,DATEADD(dd,-1,@DatumOd)) AND DATEPART(month,@DatumDo)<> DATEPART(month,DATEADD(dd,1,@DatumDo))
          BEGIN 
              SET @finalmonths = 1 
              SET @finalDays = 0
          END 
         ELSE
         BEGIN 
           SET @finalmonths = 0 
            SET @finalDays = DATEDIFF(day,@DatumOd,@DatumDo) + 1 

              END 

     
    END 
ELSE 
   BEGIN 
    SET @rawmonths = DATEDIFF(month,@DatumOd,@DatumDo)
    If DATEPART(month,@DatumOd) <> DATEPART(month,DateAdd(dd, -1, @DatumOd))
        BEGIN 
 
                    If DATEPART(month,@DatumDo) <> DATEPART(month,DateAdd(dd, 1, @DatumDo)) 
                BEGIN 
                            SET @realmonths = @rawmonths + 1
                            SET @finaldays = 0
                END 
                    Else
                BEGIN 
    
                            SET @realmonths = @rawmonths
                            SET @finaldays = Day(@DatumDo)
                        END 
        END 

    ELSE
       If DATEPART(month,@DatumDo) <> DATEPART(month,DateAdd(dd, 1, @DatumDo)) 
        BEGIN 
                    SET @realmonths = @rawmonths
                    SET @finaldays = 0
                    SET @tempdate = @DatumOd
                    While DATEPART(month,@DatumOd) = DATEPART (month,@tempdate)
            BEGIN 
                 SET @finaldays = @finaldays + 1
                             SET @tempdate = DateAdd(dd, 1, @tempdate)
            END  
        
        END 
       ELSE
                BEGIN 
            If Day(@DatumOd) = Day(@DatumDo) + 1 
             BEGIN 
                           SET @realmonths = @rawmonths
                            SET @finaldays = 0
             END 
            ELSE 
             BEGIN 
               If Day(@DatumOd) > Day(@DatumDo) + 1 
                BEGIN 
                                SET @realmonths = @rawmonths - 1
                                SET @finaldays = 0
                                SET @tempdate = @DatumOd
                                While DATEPART (month,@DatumOd) = DATEPART(month,@tempdate)
                    BEGIN 
                                       SET @finaldays = @finaldays + 1
                                       SET @tempdate = DateAdd(dd, 1, @tempdate)
                                   END 
                                SET @finaldays = @finaldays + Day(@DatumDo)
                END 
               ELSE
                BEGIN 
                    SET @realmonths = @rawmonths
                                SET @finaldays = DateDiff(day, DateAdd(mm, @realmonths, @DatumOd), @DatumDo) + 1
                END 


              END 
        END 

    END 
      SET @finalyears = CAST((@realmonths / 12) as Int)
      SET @finalmonths = @realmonths - @finalyears * 12
      
    INSERT INTO @Staz (god,mes,dan)
      VALUES (@finalyears,@finalmonths,@finalDays)

     RETURN  
    
END 




[ DarkMan @ 28.05.2008. 12:09 ] @
Ne razumem potrebu za tim kada vec postoji funkcija DATEDIFF koja upravo to radi (a i sam je koristis u svojoj funkciji).

Iz sledeceg primera se vidi da datediff uzima u obzir prestupne godine:
Code:

select datediff(day, '2008-01-01', '2008-12-31')  -- rezultat je 365
select datediff(day, '2009-01-01', '2009-12-31')  -- rezultat je 364
[ deerbeer @ 28.05.2008. 12:38 ] @
Citat:
DarkMan: Ne razumem potrebu za tim kada vec postoji funkcija DATEDIFF koja upravo to radi (a i sam je koristis u svojoj funkciji).

Iz sledeceg primera se vidi da datediff uzima u obzir prestupne godine:
Code:

select datediff(day, '2008-01-01', '2008-12-31')  -- rezultat je 365
select datediff(day, '2009-01-01', '2009-12-31')  -- rezultat je 364


Da... DATEDIFF racuna dobro prestupne godine i nije u tome problem...
Problem je da se izracuna tacno (godina,meseci,dana) za 2 zadana datuma
pa sam morao da pribegavam egzibiciji kao sto je ova gore ...

E sad kad dobijes ovaj rezultat gore sto si naveo
kako ces od njega najlakse pretvoriti u (godine,mesec,dane) ?

Npr. Covek je radio u periodu od dd/MM/yyyy do dd/MM/yyyy 2 god 6 meseci i 5 dana ...

[ DarkMan @ 28.05.2008. 12:50 ] @
Da, u tom slucaju mora da se posebno razmatraju godine, meseci i dani.
[ horabin @ 28.05.2008. 20:15 ] @
Puno hvala to je ono sto sam trazio
[ horabin @ 04.06.2008. 07:45 ] @
Funkcija ti je sasvim OK ali sam je ipak prepravio. Dao si mi ideju kako da to uradim. Kad sam je testirao cini mi se da nesto nije bilo u redu sa prestupnim godinama.

Code:
CREATE  FUNCTION  [PK].[periodGMD] (@datumOd datetime , @datumDo datetime)
RETURNS @rez TABLE (god tinyint ,mes tinyint ,dan tinyint )
AS
begin 

declare @G tinyint;
declare @M tinyint;
declare @D tinyint; 
declare @tempM int; 
declare @tempD tinyint; 
declare @tempDate datetime; 



IF DATEPART(month,@DatumOd) = DATEPART(month,@DatumDo) AND DATEPART(year,@DatumOd) = DATEPART(year,@DatumDo) 
    BEGIN 
    SET @G = 0 
        IF DATEPART(month,@DatumOd) <> DATEPART(month,DATEADD(dd,-1,@DatumOd)) AND DATEPART(month,@DatumDo)<> DATEPART(month,DATEADD(dd,1,@DatumDo))
        BEGIN 
            SET @M = 1 
            SET @D = 0
        END 
        ELSE
        BEGIN 
        SET @M = 0 
            SET @D = DATEDIFF(day,@DatumOd,@DatumDo) + 1             
        END 
    END 
ELSE
    BEGIN 
        SET @G = 0;
        SET @tempD = 0;

        IF DATEPART(dd,@datumOd) = DATEPART(dd,@datumDo) + 1
        BEGIN
            SET @tempM = DATEDIFF(mm,@datumOd,@datumDo);
            SET @M = @tempM%12;
            SET @D = 0;
            SET @G = @tempM/12;
            INSERT INTO @rez (god, mes, dan)
            VALUES(@G, @M, @D)
            RETURN
        END

        IF DATEPART(dd,@datumOd) = DATEPART(dd,@datumDo)
        BEGIN
            SET @tempM = DATEDIFF(mm,@datumOd,@datumDo);
            SET @M = @tempM%12;
            SET @D = 1;
            SET @G = @tempM/12;
            INSERT INTO @rez (god, mes, dan)
            VALUES(@G, @M, @D)
            RETURN
        END

        IF DATEPART(day,@datumOd) > DATEPART(day,@datumDo)--dan u datumOd veci od dan u datumDo
        BEGIN
            SET @tempDate = @datumOd;
            SET @tempD = datediff(dd,@datumOd,convert(datetime,('01.' + convert(char,(month(@datumOd)+1),2) + '.' + convert(char,year(@datumOd),4))));
            SET @tempM = DATEDIFF(mm,@tempDate,@datumDo) - 1;
            SET @tempDate = DATEADD(dd,@tempD,@tempDate);
            SET @tempDate = DATEADD(mm,@tempM,@tempDate);
            SET @G = @tempM/12;
            SET @M = @tempM%12;
            SET @D = DATEDIFF(dd,@tempDate,@datumDo) + @tempD + 1;
            INSERT INTO @rez (god, mes, dan)
            VALUES(@G, @M, @D)
            RETURN  
        END

        IF DATEPART(day,@datumOd) < DATEPART(day,@datumDo)--dan u datumOd manji od dan u datumDo
        BEGIN
            SET @tempM = DATEDIFF(month,@datumOd,@datumDo);
            SET @M = @tempM%12;
            SET @G = @tempM/12;
            SET @datumOd = DATEADD(mm,DATEDIFF(month,@datumOd,@datumDo),@datumOd);
            SET @D = DATEDIFF(dd,@datumOD,@datumDo) + 1;
        END
    END
INSERT INTO @rez (god, mes, dan)
VALUES(@G, @M, @D)
     RETURN  
    
END 
Edit: Dodat je code tag

[Ovu poruku je menjao chachka dana 04.06.2008. u 09:47 GMT+1]