Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Principal > Varios
Registrarse FAQ Miembros Calendario Guía de estilo Temas de Hoy

Grupo de Teaming del ClubDelphi

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 26-02-2007
Carlos Lesca Carlos Lesca is offline
Miembro
 
Registrado: sep 2005
Posts: 31
Poder: 0
Carlos Lesca Va por buen camino
Thumbs up

Cita:
Empezado por Onti
Hola Carlos:

Podrias hacer algo asi:

//. Inicializas
0. TotDias=0 ; Inicio=Fi1; Fin=Ff1

// tomas 2 fechas
1. obtienes los días entre Fi1 y Ff1 d1=dias(Fi1,Ff1)
2. obtienes los días entre Fi2 y Ff2 d2=dias(Fi2,Ff2)
3. obtienes los días comunes d3=dias(Fi2,Fin)
4. sumas TotDias=TotDias+((d1+d2)-d3)
5. actualizas Fin Fin=Ff2

// Vas al siguiente reg
6. Obtienes dias entre Fi3 y Ff3 d2=dias(Fi3,Ff3)
7. Obtienes dias comunes d3=dias(Fi3,Fin)
8. Sumas TotDias=TotDias+(d2-d3)

, etc

Es solo una idea pueden haber detalles porque lo hice a "mano a la volada"
Interesante, Creo que podria estar en el camino con tu sugerencia. Pero en el caso de en que hay dias en blanco no se si funcionaria, pero ya lo estoy probando.

Mil Gracias.
Responder Con Cita
  #2  
Antiguo 27-02-2007
Avatar de Lepe
[Lepe] Lepe is offline
Miembro Premium
 
Registrado: may 2003
Posts: 7.424
Poder: 29
Lepe Va por buen camino
Yo tengo una idea muy simple.

Usaremos un array, para que se entienda :
Código Delphi [-]
var Dias : array [fechaIni... fechaFin] of boolean;
begin

// Si trabajó el día 1 de enero de 2007
Dias[01/01/2007] := true

// Si no trabajó
Dias[01/01/2007] := false

Claro, esto no puede implementarse así de fácil, pero esa es la idea.

El punto fuerte está claro, no tendrás problemas para saber los días que ha trabajado, recorres todo el array y si tiene un true lo computas, si tiene un false no lo computas.

Añadir el periodo de fechas trabajado es muy simple... un bucle entre las dos fechas poniendo a true el día trabajado.

La desventaja es clara, si vamos a computar la vida laboral de un trabajador, serían 35 años por 365 días.... un array de 12.775 posiciones....tampoco sería muy excesivo, ya que un array son punteros y lo que guarda es un boolean.

No debería tardar mucho.

¿Como se implementa?
Vamos a usar un array dinámico
Código Delphi [-]
var Fini, Ffin :TDate;
     totDias, cont:integer;
     Dias : array of boolean;

// inicializar datos

Fini := 01/01/2007 ; // fecha inicial para computar;
FFin := Fini + (35*365); //Fecha fin dentro de 35 años;

totdias := trunc(Ffin-Fini); // restando fechas nos dan los días que han transcurrido entre ambas
SetLength(dias, totdias-1); // -1 porque empieza en cero el array
for cont:= low(dias) to high(dias) do
  dias[cont] := false; // inicializamos el array
end;


procedure anadir periodo(F1, F2:TDatetime);
  var indice, trabajados :integer;
begin
  trabajados := trunc (F2 -F1);
  indice := trunc(f1-Fini); 
// como el indice del array empieza en cero, restamos a todo Fini.
// Fini será la variable declarada anteriormente, será una global.

for cont := indice to trabajados do
 dias[cont-1] := true; // -1 porque empieza en cero el array, ¿recuerdas? 
end;

Como ves es un pseudocódigo, pero creo que puede servir.

Saludos
__________________
Si usted entendió mi comentario, contácteme y gustosamente,
se lo volveré a explicar hasta que no lo entienda, Gracias.

Última edición por Lepe fecha: 27-02-2007 a las 12:27:18.
Responder Con Cita
  #3  
Antiguo 27-02-2007
Avatar de Lepe
[Lepe] Lepe is offline
Miembro Premium
 
Registrado: may 2003
Posts: 7.424
Poder: 29
Lepe Va por buen camino
Otra cosita:

Yo todo eso lo encapsularía dentro de un TObject (una clase). De tal forma que al añadir un periodo de fechas, a la misma vez que pongo a true el índice del array incrementaría la cuenta de una variable privada "diasTrabajados", de esta forma no tendremos que recorrer todo el array para saber lo dias totales, es decir:
Código Delphi [-]

procedure anadir periodo(F1, F2:TDatetime);
  var indice, trabajados :integer;
begin
  trabajados := trunc (F2 -F1) ;
  indice := trunc(f1-Fini); 
// como el indice del array empieza en cero, restamos a todo Fini.
// Fini será la variable declarada anteriormente, será una global.

  for cont := indice to trabajados do
  begin
    if dias[cont-1] = false then inc(FDiasTrabajados);
    // si estaba a false, no estaba computado ese día
   // por tanto lo computamos ahora.

   // Si estaba a true, significa que es una fecha solapada con otro periodo
   // añadido anteriormente

    dias[cont-1] := true; // -1 porque empieza en cero el array, ¿recuerdas? 
  end;
end;

Saludos
__________________
Si usted entendió mi comentario, contácteme y gustosamente,
se lo volveré a explicar hasta que no lo entienda, Gracias.

Última edición por Lepe fecha: 27-02-2007 a las 12:27:30.
Responder Con Cita
  #4  
Antiguo 27-02-2007
Carlos Lesca Carlos Lesca is offline
Miembro
 
Registrado: sep 2005
Posts: 31
Poder: 0
Carlos Lesca Va por buen camino
Thumbs up

Cita:
Empezado por Lepe
Otra cosita:

Yo todo eso lo encapsularía dentro de un TObject (una clase). De tal forma que al añadir un periodo de fechas, a la misma vez que pongo a true el índice del array incrementaría la cuenta de una variable privada "diasTrabajados", de esta forma no tendremos que recorrer todo el array para saber lo dias totales, es decir:
Código Delphi [-] procedure anadir periodo(F1, F2:TDatetime);
var indice, trabajados :integer;
begin trabajados := trunc (F2 -F1) ; indice := trunc(f1-Fini); // como el indice del array empieza en cero, restamos a todo Fini.
// Fini será la variable declarada anteriormente, será una global.
for cont := indice to trabajados do begin if dias[cont-1] = false then inc(FDiasTrabajados);
// si estaba a false, no estaba computado ese día
// por tanto lo computamos ahora.
// Si estaba a true, significa que es una fecha solapada con otro periodo
// añadido anteriormente
dias[cont-1] := true; // -1 porque empieza en cero el array, ¿recuerdas?
end;
end;


Saludos
Interesante. Voy a verlo con mas detnimiento

Gracias.
Responder Con Cita
  #5  
Antiguo 27-02-2007
Avatar de Lepe
[Lepe] Lepe is offline
Miembro Premium
 
Registrado: may 2003
Posts: 7.424
Poder: 29
Lepe Va por buen camino
A ver... hoy estoy algo resacoso donde dice:
Código Delphi [-]
 for cont := indice to trabajados do

debe decir:
Código Delphi [-]
 for cont := indice to (indice + trabajados) do

Si trabajados tiene el valor 12 e índice tiene 7, el bucle que tiene el fallo solo constaría de 12-7 = 5 iteraciones, cuando en realidad, debe hacer 12 iteraciones.

Revisa concienzudamente el código, ya digo... la fresca rubia de anoche me dejó secuelas

Saludos
__________________
Si usted entendió mi comentario, contácteme y gustosamente,
se lo volveré a explicar hasta que no lo entienda, Gracias.
Responder Con Cita
  #6  
Antiguo 27-02-2007
Avatar de gluglu
[gluglu] gluglu is offline
Miembro Premium
 
Registrado: sep 2004
Ubicación: Málaga - España
Posts: 1.455
Poder: 21
gluglu Va por buen camino
Es muy facil. Es dificil de creer que la solución que te voy a dar es la más simple y eficiente. Puedes comprobarla, y analiza el algoritmo que te explico, y verás que es correcto.

Yo lo utilizo en mi sistema de gestión de reservas de hoteles.

1. Obtienes todos los registros de fechas de trabajo de un profesor de terminado, ordenados por fechas de inicio. (Muy importante esto último.)

2. Realizas un loop 'Do while not eof' de esos registros obtenidos, habiendo creado previamente dos variables tipo fecha, p.ej. FechaMin y FechaMax.

3. Reemplazas FechaMin y FechaMax con los respectivos valores del 1er registro.

4. Realizamos el 'Do while not eof'

Código Delphi [-]
If (Fecha Inicio Nuevo Registro <= FechaMax)
  and  (Fecha Final Nuevo Registro >= FechaMin) then begin
    if Fecha Final Nuevo Registro > FechaMax then
      FechaMax := Fecha Final Nuevo Registro
end;

Presta especial atención a lo expuesto : Tienes que comparar Fecha Inicio nuevo registro con FechaMax (<=), y Fecha Final nuevo registro con FechaMin (>=).

5. Si la condición anterior NO se cumple estamos ante un nuevo periodo de fechas que NO se solapa con ningún otro, por lo que sumamos el número de días entre FechaMin y FechaMax a una variable TotalComputo o algo parecido.

6. Procedemos de nuevo por el punto 3 con el último registro y las nuevas FechasMin y FechaMax con los respectivos valores de FechaInicio y FechaFinal

7. Al final de recorrer todos los registros, obtendrás el total de días trabajados en la variable TotalComputo.

... envío este hilo y ahora intentaré añadir otro con un código más concreto como ejemplo.
__________________
Piensa siempre en positivo !
Responder Con Cita
  #7  
Antiguo 27-02-2007
Avatar de gluglu
[gluglu] gluglu is offline
Miembro Premium
 
Registrado: sep 2004
Ubicación: Málaga - España
Posts: 1.455
Poder: 21
gluglu Va por buen camino
Intentaré hacerlo con un código 'genérico' para que sea más comprensible.

Ya lo adaptas a la base de datos que utilices.

Código Delphi [-]
Select FechaInicio, FechaFinal from FECHAS
where Profesor = CodigoSeleccionado
order by FechaInicio
 
First;
FechaMin := FechaInicio;
FechaMax := FechaFinal;
TotDiasTrabajados := 0;
 
while not Eof do begin
 
  if (FechaInicio <= FechaMax) and (FechaFinal >= FechaMin) then begin
    if FechaFinal > FechaMax then FechaMax := FechaFinal;
  end
  else begin
    TotDiasTrabajados := TotDiasTrabajados + (FechaMax - FechaMin);
    FechaMin := FechaInicio;
    FechaMax := FechaFinal;
  end;
 
  Next;
 
end;
 
TotDiasTrabajados := TotDiasTrabajados + (FechaMax - FechaMin);

Pruébalo. Espero sorprenderte con el resultado.

Un saludo.
__________________
Piensa siempre en positivo !
Responder Con Cita
Respuesta



Normas de Publicación
no Puedes crear nuevos temas
no Puedes responder a temas
no Puedes adjuntar archivos
no Puedes editar tus mensajes

El código vB está habilitado
Las caritas están habilitado
Código [IMG] está habilitado
Código HTML está deshabilitado
Saltar a Foro

Temas Similares
Tema Autor Foro Respuestas Último mensaje
Fechas en sql carymar SQL 2 15-06-2006 18:35:10
Las horribles fechas, control de fechas Huer OOP 6 18-10-2005 19:11:49
Fechas jmlifi Varios 2 11-04-2005 16:40:22
fechas davidgaldo Conexión con bases de datos 4 02-03-2004 17:21:51
Fechas Novás Varios 1 20-10-2003 13:39:57


La franja horaria es GMT +2. Ahora son las 15:24:52.


Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi
Copyright 1996-2007 Club Delphi