PDA

Ver la Versión Completa : Suma Antiguedad Laboral


shoulder
29-01-2019, 15:46:43
Una duda tengo que sumar rangos de fechas de una persona por actividad laboral:
Ej: 01/01/2015 - 02/01/2016 = 1 año y 1 un dia
01/01/2017 - 02/04/2018 = 1 año - 3 meses - 2 dias etc...


Tengo la funcion que me convierte por rango de fechas a año-mes -dia pero no encuentro nada que me sume todos los resultados y me de el valor final ya que si sumo la cantidad de dias entre todos los rangos no me da igual.


Lo que hago en ese momento es suma total de dias de todos los rangos pero se que no es real el valor.





....

...('select DATEDIFF(fecha_final,a.fecha_inicio) from antiguedad
....('where documento = :docu')...
while not zquery5.Eof do
begin
cantidaddias := zquery5.Fields[0].AsInteger + 1 ;
sumadias := sumadias + cantidaddias;
.....
zquery5.Next;
end;





dias := sumadias;
Resul:= dias/30.41;
meses := trunc(resul);

dias1 := dias mod 30;

if dias1 = 1 then dias1 := 0;
case meses of
0:
begin
edit6.Text := intToStr(dias);


end;
1..24:
begin
edit5.Text := intToStr(meses);
edit6.Text := intToStr(dias1);

end;
else
begin
edit4.Text := intToStr(meses div 12);
edit5.Text := intToStr(meses mod 12);
edit6.Text := intToStr(dias1);
end;
end;

TiammatMX
29-01-2019, 16:57:36
¿Y no te sirve calcular con DaysBetween() o alguna otra función de manejo de fechas?

shoulder
29-01-2019, 17:22:37
Si gracias pero mi duda es lo mismo calcular el day between y sumar todos los dias y de la cantidad de dias que medio dio, ejemplo : 2191 dias llevarlo a Año Mes Dia me parece que no da igual que calcular los rangos y sumar de esas partes los Años Mes Dia, porque no son dias corridos..


estoy inventando esto: no se si me da bien debo verificar.



.......................................

while not zquery5.Eof do
begin

DecodeDate(zquery5.Fields[0].AsDateTime, AAI, MMI, DDI);
DecodeDate(zquery5.Fields[1].AsDateTime, AAF, MMF, DDF);

AA := AAF - AAI;

if( MMI <= MMF ) then
MM := MMF - MMI
else
begin
MM := MMF + 12 - MMI;
AA := AA - 1;
end;

if( DDI <= DDF ) then
DD := DDF - DDI
else
begin
DD := DDF + MonthDays[IsLeapYear(AAF),MMF] - DDI;
MM := MM - 1;
end;

if MM < 0 then
begin
AA := AA - 1;
MM := 12 + MM;
end;

aa1 := aa+aa1;
mm1 := mm + mm1;
dd1 := dd + dd1;

If dd1 > 29 then
begin
dd1:= dd1 - dd;
mm1 := mm1 + 1;
end;


if mm1 > 11 then
begin
mm1 := mm1 - 12;
aa1 := aa1 + 1;

end;



zquery5.Next;
end;

edit4.Text := inttostr(aa1);
edit5.Text := inttostr(mm1);;
edit6.Text := inttostr(dd1);

Casimiro Notevi
29-01-2019, 17:58:11
Un campo fecha es un número. Si usas la función indicada por TiammatMX, te devuelve los días entre fechas. Haces la suma y listo.


select sum( DaysBetween(fechinicio,fechafin) ) as sumadias from tbTablaquesea where usuario=elusuarioquesea

shoulder
29-01-2019, 18:38:34
Gracias Casimiro entendi, pero mi pregunta es: da igual los valores en año mes dia de hacer una sumatoria de dias y ese valor descomponerlo en AAMMDD.


Que como son rangos de fechas no correlativos tomar esos rangos y descomponerlos en AAMMDD y despues sumarlos?. Al tener algo correlativo es como que dijiera 2000 dias del 01/01/2011 al 31/12/2018 y en realidad estos mismos no fueron correlativos y entre medio pudo haber existido años bisiestos o meses con 31 0 30 segun los rangos.


Perdon por si no me supe expresar.


Saludos.

ecfisa
29-01-2019, 19:46:58
Hola.

En la sección Trucos el compañero MaMu (http://www.clubdelphi.com/foros/member.php?u=8972) puso un codigo para Calcular EDAD en años, meses y dias de una Persona (http://www.clubdelphi.com/foros/showthread.php?t=80805).

Creo que con unas pocas modificaciones te serviría para el caso:

...
type
TAntiguedad = record
year : Word;
month: Word;
day : Word;
end;

function Antiguedad(Desde, Hasta: TDate): TAntiguedad;
var
a1,m1,d1: Word;
a2,m2,d2: Word;
Year, Month, Day: Word;
begin
DecodeDate(Desde, a1, m1, d1);
DecodeDate(Hasta, a2, m2, d2);

Year := a2 - a1;

if ( m1 <= m2 ) then
Month := m2 - m1
else
begin
Month := m2 + 12 - m1;
Dec(Year);
end;

if ( d1 <= d2 ) then
Day := d2 - d1
else
begin
Day := d2 + MonthDays[IsLeapYear(a2), m2] - d1;
Dec(Month);
end;

if Month < 0 then
begin
Year := Year - 1;
Inc(Month, 12);
end;

Result.year := Year;
Result.month := Month;
Result.day := Day;
end;

// Ejemplo de uso:
procedure TForm1.Button1Click(Sender: TObject);
var
d1, d2: TDate;
a: TAntiguedad;
begin
d1 := StrToDate('01/01/2017');
d2 := StrToDate('02/04/2018');
a := Antiguedad(d1, d2);
ShowMessageFmt('años:%d, meses:%d, días:%d',[a.year, a.month, a.day]); // (*)

d1 := StrToDate('29/12/2005');
a := Antiguedad(d1, Date());
ShowMessageFmt('años:%d, meses:%d, días:%d',[a.year, a.month, a.day]);
end;

(*) Fechas tomadas de tu primer mensaje y da como resultado: años: 1, meses: 3, días: 1

Saludos :)

shoulder
29-01-2019, 22:05:43
Gracias entonces despues sumo todas esas partes para que me de la totalidad de antiguedad haciendo la formula que hice mas arriba.

ecfisa
29-01-2019, 22:24:13
Hola.
Gracias entonces despues sumo todas esas partes para que me de la totalidad de antiguedad haciendo la formula que hice mas arriba.
No estoy entendiendo..., la función Antigüedad ya devuelve la totalidad del tiempo transcurrido entre fechas en años, meses y días. ¿ Por que necesitas sumar esos datos ?

Saludos. :)

mamcx
29-01-2019, 22:48:29
Date una mirada a http://www.clubdelphi.com/foros/showthread.php?t=93348, y coloca datos concretos.

Neftali [Germán.Estévez]
30-01-2019, 11:28:40
Creo que ya lo han comentado y tal vez llego tarde, pero creo que en temas de fechas la unidad "básica" es 1 día.
Por lo tanto, creo que lo más senciilo es pasar a días cada uno de los intervalos y una vez tengas los días totales, pasar eso al tipo Antiguedad (es decir, sacar los años, meses y días a partir del total de días).