|
[ 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]
Copyright (C) 2001-2025 by www.elitesecurity.org. All rights reserved.
|